问题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. Centos6.5安装memcached

    1.检查libevent 首先检查系统中是否安装了libevent(Memcache用到了libevent这个库用于Socket的处理). # rpm -q libevent libevent-1.4 ...

  2. Java IO详解(二)------流的分类

    一.根据流向分为输入流和输出流: 注意输入流和输出流是相对于程序而言的. 输出:把程序(内存)中的内容输出到磁盘.光盘等存储设备中      输入:读取外部数据(磁盘.光盘等存储设备的数据)到程序(内 ...

  3. CompletionService 简介

    以下是jdk关于CompletionService的简介: public interface CompletionService<V> 将生产新的异步任务与使用已完成任务的结果分离开来的服 ...

  4. 关于MySQL数据库的一些操作

    启动:net start MySQL 关闭:net stop MySQL (也可以用quit:) 登录到MySQL:mysql -u root -p -u : 所要登录的用户名; -p : 告诉服务器 ...

  5. laravel实现多数据库连接配置

    只需三步,便可实现. 第一步,在.env文件中配置 DB_HOST=localhost DB_DATABASE=test DB_USERNAME=root DB_PASSWORD=root DB_HO ...

  6. 刨根究底字符编码之八——Unicode编码方案概述

    Unicode编码方案概述   1. 前面讲过,随着计算机发展到世界各地,于是各个国家和地区各自为政,搞出了很多既兼容ASCII但又互相不兼容的各种编码方案.这样一来同一个二进制编码就有可能被解释成不 ...

  7. 红包项目总结---MVC版

    起因: 针对传统版的明显缺陷做优化.主要是提升可维护性. 效果  线上:  未发布 线下:http://10.27.5.1/svn/FED/code/hongbao/year-end   hb-fac ...

  8. HTML输入框只能输入数字或数字字母组合

    JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入) <input onkeyup="this.value=this.value.replace(/\D/g,'' ...

  9. 初入计算机图形学(二):对bidirectional path tracing的一些困惑

    本人水平有限,若有错误也请指正~ 前文提及了光线追踪的一些常用手法,但是其中path tracing的实现最为简单,但是其最致命的一个缺点就是图像收敛速度很慢..原因在于从摄影机发射出的每一条光线若不 ...

  10. Java中设计模式之单例设计模式-1

    单例作用 1 节省内存 2 可以避免多种状态导致状态冲突 单例的创建步骤 1 私有化构造方法 2 私有化声明的属性 3 getInstance 4 方法需要静态 单例分类 1.懒汉式 2.饿汉式 两种 ...