理解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的问题. 随笔虽长,但我相信 ...
随机推荐
- JavaScript知识点整理(一)
JavaScript知识点(一)包括 数据类型.表达式和运算符.语句.对象.数组. 一.数据类型 1) js中6种数据类型:弱类型特性 5种原始类型:number(数字).string(字符串).bo ...
- jQuery之文档处理
jQuery 文档处理 1)内部插入 2)外部插入 3)包裹 4)替换 5)删除 6)复制 1.内部插入 append(content|fn) 向每个匹配的元素内部追加内容. 向所有段落中追加一些HT ...
- 获取JUnit的执行结果
junit执行之后会有一个结果展示,下面就来看一下怎么获取这些结果并将其存储为一个对象 junit代码如下: package test; import org.junit.After; import ...
- Android 桌面不显示应用图标
忽然有一天,运行自己的程序,发现桌面没有应用图标了. google了半天,也没什么发现. 最后发现是主Activity中: <action android:name="android. ...
- JBoss7 如何用脚本 启动 和 停止
用脚本来启动/停止JBoss服务器,有助于开发部署的 自动执行,提高工作效率. 在JBoss以前的版本中,很容易在bin目录下面找到 启动和停止服务器的脚本: run.bat shutdown.bat ...
- slideToggle+slideup实现手机端折叠菜单效果
折叠菜单的效果,网上有很多的插件,比如bootstrap的 Collapse ,很好用也很简单,但是如果你使用的不是bootstrap框架,就会造成很多不必要的麻烦,比如默认样式被修改,代码冗余等等, ...
- angularjs里重要的route
写一段代码来解释吧! <!DOCTYPE html><html ng-app="mainApp"><head lang="en"& ...
- CentOS下SparkR安装部署:hadoop2.7.3+spark2.0.0+scale2.11.8+hive2.1.0
注:之前本人写了一篇SparkR的安装部署文章:SparkR安装部署及数据分析实例,当时SparkR项目还没正式入主Spark,需要自己下载SparkR安装包,但现在spark已经支持R接口,so更新 ...
- Python可视化:Seaborn库热力图使用进阶
前言 在日常工作中,经常可以见到各种各种精美的热力图,热力图的应用非常广泛,下面一起来学习下Python的Seaborn库中热力图(heatmap)如何来进行使用. 本次运行的环境为: windows ...
- 小K的H5之旅-HTML的基本结构与基本标签
一.什么是HTML HTML是超文本标签语言,即网页的源码.而浏览器就是翻译解释HTML源码的工具. 二.HTML文档的结构 HTML文档主要包括三大部分:文档声明部分.<head>头部部 ...