MySQL的存储引擎造成的事务无法回滚

团队技术核心成员写的,这个问题,导致其开发的销售模块事务无法回滚,数据库外键均变成索引

原博客:http://blog.csdn.net/lzx_longyou/article/details/50446206

最近在做一个项目,用的是hibernate框架,数据库是mysql。我是在javaweb的过滤器上通过session与线程绑定,得到当前线程绑定的session然后开启事务,然后进行放心,对异常进行捕获并回滚。这是在没有使用spring框架的事务处理,而又为了延长hibernate中session的声明周期所采用的方法,即OpenSessinInView。在过滤器开启事务后,放行执行的代码都会在事务之内,出现异常进行捕获可以回滚。代码如下:

[java]  view plain copy
  1. public class OpenSessionInView implements Filter {  
  2.   
  3.     public void doFilter(ServletRequest request, ServletResponse response,  
  4.             FilterChain chain) throws IOException, ServletException {  
  5.         Session session = null;  
  6.         Transaction tx = null;  
  7.         try {  
  8.             session = ClientSessionFactory.getCurrentSession();  
  9.             tx = session.beginTransaction();  
  10.             //=======业务开始=======  
  11.             chain.doFilter(request, response);  
  12.             //=======业务结束=======  
  13.               
  14.             tx.commit();  
  15.         } catch (AjaxException e) {  
  16.             response.setCharacterEncoding("utf-8");  
  17.             if (tx != null) {  
  18.                 tx.rollback();  
  19.             }  
  20.             String error = e.getMessage();  
  21.             response.getWriter().print(error);  
  22.         } catch (Exception e) {  
  23.             if (tx != null) {  
  24.                 tx.rollback();  
  25.             }  
  26.             e.printStackTrace();  
  27.             request.setAttribute("error", e.getMessage());  
  28.             request.getRequestDispatcher("/jsps/error.jsp")  
  29.                     .forward(request, response);  
  30.         } finally{  
  31.             ClientSessionFactory.closeCurrentSession();  
  32.         }  
  33.     }  
  34.   
  35.     public void init(FilterConfig fConfig) throws ServletException {  
  36.           
  37.     }  
  38.   
  39.     public void destroy() {  
  40.           
  41.     }  
  42.   
  43. }  

在实际情况中,我在servlet中执行了一个添加函数,往数据库中添加一条记录,然后继续执行下面的代码,结果发生了异常。这时发现,数据库中的数据并没有回滚。在设置断点调试后,发现,过滤器中的事务有开启,异常也有被捕获,事务回滚的代码也有被执行,但是数据库中的数据就是不回滚,造成了垃圾数据的产生。

同时,也发现了数据库中存在的一个问题,所有建的外键,都无效,自动变成了索引,真的是奇怪。

后来在网上找了很久,才发现这不是代码的问题,而是数据库的问题。MySQL数据库的存储引擎有好几种,有的不支持事务和外键,有的支持。在mysql中输入sql语句 SHOW ENGINES可以查看当前数据库支持的引擎:



第二列Support中DEFAULT表示目前数据库的默认引擎。这个引擎是管理非事务表,不支持事务,不支持外键,但是访问速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用基本都可以使用这个引擎来创建表。这也就解释了我遇到的数据库不能回滚,表不能建外键的原因。

从图中可以看到,只有InnoDB这个引擎支持了事务,所以想在程序中使用事务,并在出现异常时回滚,就要使用这个引擎,即修改一下表的引擎即可。

至此之前的问题都解决了。有时候思考一个问题,不能太单方面,从多角度思考或许就能找到问题的根源。

关于MySQL数据库引擎的介绍,可参考下面一篇博客:

http://www.cnblogs.com/gbyukg/archive/2011/11/09/2242271.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值