理解Hibernate事务机制,首先需要搞清楚的6个问题
问题1:到底该用getTransaction还是beginTransaction?

上图说明的问题:
- 第1步,调用session.getTransaction()的时候,会创建一个全新的Transaction对象;
- 第2步,调用session.beginTransaction()的时候,会创建一个全新的Transaction对象,没有使用上一步的Transaction对象哦;
- 第3步,再次调用session.getTransaction()的时候,会看到这时返回的是第2步创建的Transaction对象;
- 第4步,这时调用session.getCurrentTransaction(),会看到仍然返回第2步创建的Transaction对象;
结论:通常情况下一个session内只会处理一个事务,所以大多数时候可直接调用session.beginTransaction()方法创建一个全新的transaction对象,并开始该事务。
问题2:getCurrentTransaction跟getTransaction有什么区别?

上图说明的问题:
- 第1步,直接调用session.getCurrentTransaction()会返回null;
- 第2步,调用session.beginTransaction() 会创建一个全新的Transaction对象;
- 第3步和第4步说明,当session.beginTransaction()被调用后,不管使用session.getTransaction()还是session.getCurrentTransaction()都是返回beginTransaction时创建的同一个Transaction对象。
结论:当session.beginTransaction被调用之后,不管是用session.getTransaction还是getCurrentTransaction返回的都是同一个transaction对象;如果没有开始事务,getTransaction会创建一个新的transaction对象,getCurrentTransaction会返回null。
问题3:如果不断的调用getTransaction,是否会返回同一个transaction对象?

结论:上图说明,每次调用session.getTransaction()都会创建全新的Transaction对象,如果是这样,那这个方法如果叫session.createTransaction()或许更加合理,但是呢,如果session已经有begin了的transaction,该方法又不会创建新的transaction。所以说,这个命名真的是一个巨大的坑,在程序中应该避免使用这个方法,否则难以理解是否是同一个Transaction对象;
问题4: 通过getTransaction创建的transaction对象begin之后,再次调用session.beginTransaction是否会开启两个事务?

结论:上图说明,session.getTransaction().begin() 与 session.beginTransaction() 是完全一模一样的。一个session同时只能有一个transaction是active的(开启状态)。
那么,既然一个session可以通过session.getTransaction()创建无数个Transaction实例,那么这些Transaction实例是否可以独立工作呢?但是下方的最后一行代码就报错了:
Transaction transaction1 = db.getSession().getTransaction();
Transaction transaction2 = db.getSession().getTransaction();
transaction1.begin();
transaction2.begin();
原因就是一个session不能同时开启多个transaction。
问题5:当transaction.commit()调用之后再次调用session.beginTransaction是否会继续沿用之前的transaction?

上图说明的问题:
- 一个session里面是可以开启多个transaction的,但是一个transaction的begin方法只有在其他transaction都不是active的时候才可以调用成功,也就是说一个session同时仅允许一个active的transaction;
- 当一个transaction.commit() 方法调用之后,再次调用session.getTransaction()就会创建一个全新的Transaction对象,这一点非常重要,千万不要以为同一个session在调用transaction.begin()之后再调用session.getTransaction()都只会返回同一个Transaction对象,如果之前begin的那个transaction已经commit,这时再调用session.getTransaction()就是全新的transaction对象了。
问题6:是否总是需要手工调用transaction.rollback实现事务回滚?
问题:假如一个transaction.commit()方法提交了2条sql,但是第2条由于数据验证错误而抛了异常,那么请问,如果不手工调用transaction.rollback()方法,该transaction的第1条sql是否会执行成功。
答案:不会执行成功。这个结论告诉我们,如果之前没有调用session.flush()而是最后一起执行transaction.commit(),那么不需要加try-catch来手工调用transaction.rollback()
问题7:开启事务之后,如果session执行了直接的sql,当事务回滚时该sql影响是否会回滚?
问题:
答案:
本文中的测试来自jframe 框架
基于spring mvc搭建的多层级多模块java web应用程序框架。包含:基础设施层、数据库定义规范、数据库访问规范、日志记录规范、多层级异常捕获、标准ajax规范、母版页规范、视图呈现规范、JavaScript框架规范等。实际上该框架定义的规范极其详细,比如数据库定义层:枚举类使用规范、datetime/bool/string字段规范、1对1、1对多、多对1、多对多外键关系映射规范、父类定义规范、字段注释规范、懒加载规范等等。。。
技术交流QQ群:651499479,欢迎java大神指点迷津,也欢迎新手进群学习。
github地址: https://github.com/leotsai/jframe
THE END.
理解Hibernate事务机制,首先需要搞清楚的6个问题的更多相关文章
- hibernate 事务理解
简介: Hibernate本身并不具备事务管理能力 .在事务管理层, Hibernate将其委托给底层的JDBC或者JTA ,以实现事务管理和调度功能. Hibernate的默认事务处理机制基于JDB ...
- atitit.spring hibernate的事务机制 spring不能保存对象的解决
atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...
- Hibernate 事务和并发控制
首先关于Hibernate事务控制,下面是非常权威的资料, https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch02.html ...
- hibernate缓存机制详细分析 复制代码 内部资料 请勿转载 谢谢合作
您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...
- REDIS 事务机制
基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务 ...
- hibernate缓存机制详细分析
转自:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级 ...
- 10.hibernate缓存机制详细分析(转自xiaoluo501395377)
hibernate缓存机制详细分析 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论 ...
- hibernate缓存机制详细介绍
hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别). 一:hibernate的 N+1问题 list()获得对象: 如果通过list()方法 ...
- hibernate缓存机制详细分析(一级、二级、查询缓存,非常清晰明白)
本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题. 随笔虽长,但我相信 ...
随机推荐
- 《快学Scala》——控制结构和函数
条件表达式 在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值.例如: if (x > 0) 1 else -1 上述表达式的值是1或-1,具体是哪一个取决于x ...
- 刚由pc端做移动端的感受
最近新调到一个项目,由原来的pc端,调到移动端,一切都是那么的不一样,在得知即将调到移动端的时候,听说我们的技术要用到vue,Aladdin,还有es6,有点懵... 我做了以下准备工作: 1,买了本 ...
- redis连接池的使用方法
所需jar:jedis-2.8.0.jar和commons-pool-2-2.3jar Jedis操作步骤如下:1->获取Jedis实例需要从JedisPool中获取:2->用完Jedis ...
- 学习MVC之租房网站(八)- 前台注册和登录
在上一篇<学习MVC之租房网站(七)-房源管理和配图上传>完成了在后台新增.编辑房源信息以及上传房源配图的功能.到此后台开发便告一段落了,开始实现前台的功能,也是从用户的登录.注册开始. ...
- sqlmap连接Mysql实现getshell(原创)
前言 昨天群友发了一知乎的帖子..才发现sqlmap玩了那么久有些玩意我居然没玩过...然后看着群友玩= =今天也想试试. 0x01 首先得知道这个玩意,sqlmap -help,不说大家也懂搜嘎. ...
- 【linux命令】打开关闭防火墙iptables
防火墙关闭 关闭防火墙(linux) 经过自己的实验,发现在ubuntu中service iptables 无法使用. 同时,在init.d中并没有iptables的程序,iptables程序在/sb ...
- trap-接收信号_采取行动
trap命令用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作. kill和trap等都可以看到信号编号及其关联的名称. "信号"是指那些被异步发送到 ...
- 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL
树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构. a.树是n ...
- 读Zepto源码之集合操作
接下来几个篇章,都会解读 zepto 中的跟 dom 相关的方法,也即源码 $.fn 对象中的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码 ...
- 《Android进阶》之第六篇 Fragment 的使用2
最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...