操作订单时出现的事务问题

今天在操作订单的代码时,控制台总是报出反射方法内部出现问题,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();写在了红色的/////出,这就导致每次循环产生的订单项都是同一个,因为这里只产生了一个订单对象,而且是购物车集合中的最后一个,因为每次加载后面的总是会覆盖前面的内容。
时间: 2024-10-06 03:05:14

操作订单时出现的事务问题的相关文章

C#操作Excel时的格式设定(转)

Excel报表打印的格式设定 1.     表头的设置 Excel._Worksheet myWorksheet; myWorksheet.PageSetup.Orientation = Excel.XlPageOrientation.xlLandscape; //纸张方向, 返回或者设置对象的方向, 纵向或横向打印模式 //Excel.XlPageOrientation.xlLandscape   landscape mode  :worksheet横幅 //Excel.XlPageOrien

C#操作word时出现的office错误

每次运行WORD都会出现一个提示窗口--"此错误通常是由宏安全性设置造成的.如果您知道宏来自您信任的来源,则可将宏安全性设置更改为允许启用宏.宏安全性设置的更改方式取决于您使用的Microsoft Office System 程序." Word2007提示错误"此错误通常是由宏安全性设置造成"的解决方法有以下几种: 方法一: Word选项--加载项--管理[com加载项],转到--把几个勾勾都取消掉--确定,即可.Win7中注意要以管理员身份进行,因为这些写入了注册

Spring AOP操作action时无法注入,报NullPointer异常

Spring AOP操作action时无法注入,报NullPointer异常当使用Spring AOP对action层进行操作时,会出现注入失败的问题,出现空指针异常.原因是一般struts2+spring应用中,spring的插件只负责为action的ioc部分,但并没有进行功能加强,即采用代理的机制,所有的action还是使用struts2进行管理,在使用AOP后,这些action需要由spring进行管理,如果没有由spring进行代理,将出现注入失败.解决办法:Struts2的一个特殊的

有时候在操作Session时,系统会抛出如下异常:java.lang.IllegalStateException: Cannot create a session after the response has been committed

有时候在操作Session时,系统会抛出如下异常 java.lang.IllegalStateException: Cannot create a session after the response has been committed 原因1: Session 的创建语句: HttpSession seesion = request.getSession(); 之前有Response的输出语句. 应该把HttpSession seesion = request.getSession(); 放

数据库操作之整合Mybaties和事务讲解 5节课

1.SpringBoot2.x持久化数据方式介绍          简介:介绍近几年常用的访问数据库的方式和优缺点 1.原始java访问数据库             开发流程麻烦             1.注册驱动/加载驱动                 Class.forName("com.mysql.jdbc.Driver")             2.建立连接                 Connection con = DriverManager.getConnec

小D课堂【SpringBoot】数据库操作之整合Mybaties和事务讲解

========================8.数据库操作之整合Mybaties和事务讲解 5节课================================ 加入小D课堂技术交流答疑群:Q群:699347262 1.SpringBoot2.x持久化数据方式介绍 简介:介绍近几年常用的访问数据库的方式和优缺点 1.原始java访问数据库 开发流程麻烦 1.注册驱动/加载驱动 Class.forName("com.mysql.jdbc.Driver") 2.建立连接 Connec

看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制

第一部分 基本设计 目前最新版本的C#驱动MongoDB-CSharpDriver-2.2.3,比之前的版本更新比较大,在网上很难找到这个版本的相关C#操作资料,以下都是个人自发研究.测试的,如有雷同,不胜荣幸:如觉不妥,留言喷射:如有错误,还请赐教:如获帮助,示意欣赏.新版中有很多异步操作,本人对此没作研究,怕会产生数据安全问题,所以全部用的是同步方法. 1. 模型设计,使用GUID类型做为Id属性,在初始化时给一个随机值,基类代码,不作解释 using System;using System

看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制之 第二部分

第二部分 尝试解决BulkWrite(List<WriteModel<T>>)问题 在上次发表的文章中,得到了一些很好的反馈,真切体会到写博文的好处,有高人指出两大问题,具体可以看看上篇中的评论,下面依然是发表一些个人见解,只做研究,并不保证解决实际问题. 这两大问题终究来说,是发生在BulkWrite(List<WriteModel<T>>)上,针对@ 从来不用 的问题,我试着找出影响的行数据还比对写入操作的数量,如果一致,则提交,如果不一致则回滚. 1.

Django操作model时,报错:AttributeError:’ProgrammingError’ object has no attribute ‘__traceback__’

原因:在Django项目下相应的应用下面的models.py配置的model(也就是class)没有创建成相应的表. 这是怎么回事呢? 首先,将models.py里面的model创建成对应的数据库表的执行命令(DOS命令)为:manage.py syncdb. 但是我自己的电脑上执行该命令时,显示.Unknown command:syncdb.执行,manage.py help后的确没有发现这个子命令.最后网上搜索发现这个命令已经在Django1.9里面取消了.并且stackoverflow里面