您的位置:首页 > 数据库 > MySQL

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

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

public class OpenSessionInView implements Filter {

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
Session session = null;
Transaction tx = null;
try {
session = ClientSessionFactory.getCurrentSession();
tx = session.beginTransaction();
//=======业务开始=======
chain.doFilter(request, response);
//=======业务结束=======

tx.commit();
} catch (AjaxException e) {
response.setCharacterEncoding("utf-8");
if (tx != null) {
tx.rollback();
}
String error = e.getMessage();
response.getWriter().print(error);
} catch (Exception e) {
if (tx != null) {
tx.rollback();
}
e.printStackTrace();
request.setAttribute("error", e.getMessage());
request.getRequestDispatcher("/jsps/error.jsp")
.forward(request, response);
} finally{
ClientSessionFactory.closeCurrentSession();
}
}

public void init(FilterConfig fConfig) throws ServletException {

}

public void destroy() {

}

}


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

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

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



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

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

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

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

http://www.cnblogs.com/gbyukg/archive/2011/11/09/2242271.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql hibernate