zoukankan      html  css  js  c++  java
  • 操作订单时出现的事务问题

    今天在操作订单的代码时,控制台总是报出反射方法内部出现问题,debug仔细查找后,确定问题出现在dao层:

    下面是我写的具体的订单dao

    • public class OrderDao {
    • QueryRunner qr = new QueryRunner();
    • //当点击意见购买时生成订单即往订单表中插入订单
    • public void addOrder(Order order){
    • //得到数据库连接
    • Connection con = null;
    • try {
    • con = JdbcUtils.getConnection();
    • String sql = "insert into orders values(?,?,?,?,?,?)";
    • //将下单时间转换为SQLdate
    • Timestamp ts = new Timestamp(order.getOrdertime().getTime());
    • Object [] params = {order.getOid(),ts,order.getTotal(),
    • order.getState(),order.getUser().getUid(),order.getAddress()};
    • qr.update(con, sql, params);

    } catch (SQLException e) {

    • throw new RuntimeException(e);
    • }finally{
    • try{if(con!=null){con.close();}}catch(SQLException e){throw new RuntimeException(e);}
    • }
    • }
    • //向表单中添加表单项
    • public void addOrderItem(List<OrderItem> orderitem){
    • Connection con = null;
    • try {
    • con = JdbcUtils.getConnection();
    • String sql = "insert into orderitem values(?,?,?,?,?)";
    • Object [][] params = new Object[orderitem.size()][];
    • for(int i=0;i<orderitem.size();i++){
    • OrderItem item = orderitem.get(i);
    • params[i] = new Object[]{item.getIid(),item.getCount(),
    • item.getSubtotal(),item.getOrder().getOid(),
    • item.getBook().getBid()};
    • }
    • qr.batch(con, sql, params);
    • } catch (SQLException e) {
    • throw new RuntimeException(e);
    • }finally{
    • try{if(con!=null){con.close();}catch(SQLException e){throw new RuntimeException(e);}
    • }

    }

    而在service层上面两个方法是包含在同一个事务中,如下所示:

    • public void addOrder(Order order){
    • OrderDao dao = new OrderDao();
    • try {
    • //开启事务
    • JdbcUtils.beginTransaction();
    • dao.addOrder(order);
    • dao.addOrderItem(order.getOrderitemlist());
    • JdbcUtils.commitTransaction();
    • } catch (SQLException e) {
    • System.out.println("asdf");
    • try {
    • //回滚事务
    • JdbcUtils.rollBack();
    • } catch (SQLException e1) {
    • throw new RuntimeException(e);
    • }
    • throw new RuntimeException(e);
    • }
    • }

    如上的红色部分是问题的关键,由于在service层中它两所处在同一个事务,所以其中一个一旦关闭连接,就因为无法正常运行另外一个方法而导致SQL异常,最后的解决办法是,我封装了一个JdbcUtils工具类,它有一个释放链接的方法,会先判断事务是否还在使用连接,如果使用就不关闭,如果不使用,就关闭连接。所以红色出现问题的地方应该改为JdbcUtils.releaseConnection(con);问题解决。

    -----------------------------------------------------------------------------------------------------

    问题二:在表单的servlet层发现当用户在选择同一本书时不会出现问题,而购买多种图书时,就会爆出SQL异常说是同一个key值不能插入多条数据。源码如下:

    • public class OrderServlet extends BaseServlet {
    • public String addOrder(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    • //从购物车中获取订单

    Cart cart = (Cart) request.getSession().getAttribute("cart");

    • //封装订单
    • Order order = new Order();
    • order.setOid(CommonUtils.uuid());
    • order.setOrdertime(new Date());
    • order.setTotal(cart.getTotal());
    • order.setState(1);
    • order.setUser((User)request.getSession().getAttribute("user"));
    • //封装订单项
    • Collection<CartItem> col = cart.getCartItems();
    • List<OrderItem> orderItemList = new ArrayList<OrderItem>();
    • ////////////////////////////////
    • ///////////////////////////////
    • for(CartItem ci:col){
    • OrderItem oi = new OrderItem();
    • oi.setBook(ci.getBook());
    • oi.setCount(ci.getCount());
    • oi.setIid(CommonUtils.uuid());
    • oi.setSubtotal(ci.getTotal());
    • oi.setOrder(order);
    • orderItemList.add(oi);
    • }
    • order.setOrderitemlist(orderItemList);
    • //清空购物车
    • cart.clear();
    • //调用service方法
    • orderService os = new orderService();
    • os.addOrder(order);
    • request.setAttribute("order", order);
    • return "f:/item/jsps/order/desc.jsp";
    • }
    • }

    debug之后发现,选择多种图书时,购物车中没有问题即session没有问题,而是在添加表单项时,原先的图书种类都变成了同一种,仔细研究才发现将

    • OrderItem oi = new OrderItem();写在了红色的/////出,这就导致每次循环产生的订单项都是同一个,因为这里只产生了一个订单对象,而且是购物车集合中的最后一个,因为每次加载后面的总是会覆盖前面的内容。
  • 相关阅读:
    求最大公约数
    计算变量
    JavaScript高级浏览器原理V8引擎js执行原理
    JavaScript小游戏按下按钮移动方块
    黑马程序员WPF中的DoubleAnimation
    黑马程序员浅谈partial class的理解
    黑马程序员C#与Javascript变量、函数之间的相互调用
    黑马程序员关于工作流的模式
    黑马程序员C#解析HTML
    黑马程序员关于System.Collections空间
  • 原文地址:https://www.cnblogs.com/itzfz/p/6132375.html
Copyright © 2011-2022 走看看