MySQL的存储引擎造成的事务无法回滚
2016-01-01 23:41
681 查看
最近在做一个项目,用的是hibernate框架,数据库是mysql。我是在javaweb的过滤器上通过session与线程绑定,得到当前线程绑定的session然后开启事务,然后进行放心,对异常进行捕获并回滚。这是在没有使用spring框架的事务处理,而又为了延长hibernate中session的声明周期所采用的方法,即OpenSessinInView。在过滤器开启事务后,放行执行的代码都会在事务之内,出现异常进行捕获可以回滚。代码如下:
在实际情况中,我在servlet中执行了一个添加函数,往数据库中添加一条记录,然后继续执行下面的代码,结果发生了异常。这时发现,数据库中的数据并没有回滚。在设置断点调试后,发现,过滤器中的事务有开启,异常也有被捕获,事务回滚的代码也有被执行,但是数据库中的数据就是不回滚,造成了垃圾数据的产生。
同时,也发现了数据库中存在的一个问题,所有建的外键,都无效,自动变成了索引,真的是奇怪。
后来在网上找了很久,才发现这不是代码的问题,而是数据库的问题。MySQL数据库的存储引擎有好几种,有的不支持事务和外键,有的支持。在mysql中输入sql语句 SHOW ENGINES可以查看当前数据库支持的引擎:
第二列Support中DEFAULT表示目前数据库的默认引擎。这个引擎是管理非事务表,不支持事务,不支持外键,但是访问速度快,对事务完整性没有要求或者以SELECT、INSERT为主的应用基本都可以使用这个引擎来创建表。这也就解释了我遇到的数据库不能回滚,表不能建外键的原因。
从图中可以看到,只有InnoDB这个引擎支持了事务,所以想在程序中使用事务,并在出现异常时回滚,就要使用这个引擎,即修改一下表的引擎即可。
至此之前的问题都解决了。有时候思考一个问题,不能太单方面,从多角度思考或许就能找到问题的根源。
关于MySQL数据库引擎的介绍,可参考下面一篇博客:
http://www.cnblogs.com/gbyukg/archive/2011/11/09/2242271.html
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中的integer 数据类型
- MySQL存储过程
- mysql中int、bigint、smallint 和 tinyint的区别与长度
- mysql load data 导出、导入 csv
- source命令执行SQL脚本文件
- MySQL创建用户及权限控制
- MySQL管理数据表
- linux下mysql添加用户
- mysql procedure
- mysql触发器
- MySQL 备份和恢复策略
- mac下安装mysql(转载)
- mysql 修改编码 Linux/Mac/Unix/通用(杜绝修改后无法启动的情况!)
- MySQL数据的导出、导入(mysql内部命令:mysqldump、mysql)
- mysql数据行转列
- Linux下修改MySQL编码的方法
- MySQL Server 日志
- MySQL 安全事宜
- MySQL 备份与恢复