问题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?

上图说明的问题:

  1. 一个session里面是可以开启多个transaction的,但是一个transaction的begin方法只有在其他transaction都不是active的时候才可以调用成功,也就是说一个session同时仅允许一个active的transaction;
  2. 当一个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个问题的更多相关文章

  1. hibernate 事务理解

    简介: Hibernate本身并不具备事务管理能力 .在事务管理层, Hibernate将其委托给底层的JDBC或者JTA ,以实现事务管理和调度功能. Hibernate的默认事务处理机制基于JDB ...

  2. atitit.spring hibernate的事务机制 spring不能保存对象的解决

    atitit.spring hibernate的事务机制 spring不能保存对象的解决 sessionFactory.openSession() 不能..log黑头马sql语言.. sessionF ...

  3. Hibernate 事务和并发控制

    首先关于Hibernate事务控制,下面是非常权威的资料, https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch02.html ...

  4. hibernate缓存机制详细分析 复制代码 内部资料 请勿转载 谢谢合作

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  5. REDIS 事务机制

    基本事务操作: 任何数据库都必须要保证一种原子执行操作:最基本的原子执行操作肯定是需要提供: 举一个例子来说明: 当对某个Key 做一个统计: 可能不同的Client做它那部分的统计,一段时间后,服务 ...

  6. hibernate缓存机制详细分析

    转自:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级 ...

  7. 10.hibernate缓存机制详细分析(转自xiaoluo501395377)

    hibernate缓存机制详细分析   在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论 ...

  8. hibernate缓存机制详细介绍

    hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别). 一:hibernate的 N+1问题 list()获得对象: 如果通过list()方法 ...

  9. hibernate缓存机制详细分析(一级、二级、查询缓存,非常清晰明白)

    本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session级别).二级缓存(sessionFactory级别)以及查询缓存,当然还要讨论下我们的N+1的问题. 随笔虽长,但我相信 ...

随机推荐

  1. 《快学Scala》——控制结构和函数

    条件表达式 在Scala中if/else表达式有值,这个值就是跟在if或else之后的表达式的值.例如: if (x > 0) 1 else -1 上述表达式的值是1或-1,具体是哪一个取决于x ...

  2. 刚由pc端做移动端的感受

    最近新调到一个项目,由原来的pc端,调到移动端,一切都是那么的不一样,在得知即将调到移动端的时候,听说我们的技术要用到vue,Aladdin,还有es6,有点懵... 我做了以下准备工作: 1,买了本 ...

  3. redis连接池的使用方法

    所需jar:jedis-2.8.0.jar和commons-pool-2-2.3jar Jedis操作步骤如下:1->获取Jedis实例需要从JedisPool中获取:2->用完Jedis ...

  4. 学习MVC之租房网站(八)- 前台注册和登录

    在上一篇<学习MVC之租房网站(七)-房源管理和配图上传>完成了在后台新增.编辑房源信息以及上传房源配图的功能.到此后台开发便告一段落了,开始实现前台的功能,也是从用户的登录.注册开始. ...

  5. sqlmap连接Mysql实现getshell(原创)

    前言 昨天群友发了一知乎的帖子..才发现sqlmap玩了那么久有些玩意我居然没玩过...然后看着群友玩= =今天也想试试. 0x01 首先得知道这个玩意,sqlmap -help,不说大家也懂搜嘎. ...

  6. 【linux命令】打开关闭防火墙iptables

    防火墙关闭 关闭防火墙(linux) 经过自己的实验,发现在ubuntu中service iptables 无法使用. 同时,在init.d中并没有iptables的程序,iptables程序在/sb ...

  7. trap-接收信号_采取行动

    trap命令用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作. kill和trap等都可以看到信号编号及其关联的名称. "信号"是指那些被异步发送到 ...

  8. 数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

    树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n ...

  9. 读Zepto源码之集合操作

    接下来几个篇章,都会解读 zepto 中的跟 dom 相关的方法,也即源码 $.fn 对象中的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码 ...

  10. 《Android进阶》之第六篇 Fragment 的使用2

    最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...