`

Hibernate(20):默认情况下决定commit时session命运的三个条件

阅读更多

    Hibernate(十九): 异常"Session was already closed" 中,针对"Session was already closed"异常,我们发现最终调用了transactionContext.managedClose方法来关掉了session, 那么这个过程具体是什么样的? 这篇中将加以梳理 .

    在JDBCTransaction类(Transaction接口的一个实现类)具体决定是否要关session的方法closeIfRequired 里, 有这么一个复合条件决断: if(callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ). 这三个条件分别代表什么?

    首先看这个
callback, 在 JDBCTransaction 类的begin方法里(session.beginTransaction()方法最终要调用这个begin),看到这样的赋值: callback = jdbcContext.registerCallbackIfNecessary();
   
registerCallbackIfNecessary方法的实现有些奇怪, 如下所示:

     public boolean registerCallbackIfNecessary() {
        if ( isTransactionCallbackRegistered ) {
            return false;
        }
        else {
            isTransactionCallbackRegistered = true;
            return true;
        }
    }
   
如果isTransactionCallbackRegistered 为true就返回false, 如果是false,把它set为true后返回true. 有些奇怪. 不过, 这里不过多讨论了, debug时发现这里返回的是true.

    再看第二个
transactionContext.shouldAutoClose().这里的主角transactionContextTransactionFactory.Context接口, 它什么时候set到 JDBCTransaction 类的, JDBCTransaction类的构造方法里,即JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext). 为了追 transactionContext是从哪来的,看 这个构造方法又是何时调用. JDBCTransactionFactory里的createTransaction方法, 这个方法又在JDBCContext类的createTransaction( this, owner ) 里,这里的的owner就是我们一直追的transactionContext, 那么这个owner是什么它又来自何方呢? 来自JDBCContext(Context owner, Connection connection, Interceptor interceptor)构造方法.如下是整个跟踪路径:


最终在SessionImpl类的构造方法里对jdbcContext的赋值语句看到了,owner就是this,即SessionImpl对象.

    this.jdbcContext = new JDBCContext( this, connection, interceptor );
也就是说SessionImpl类实现了TransactionFactory.Context接口(以实现JDBCContext.Context子接口方式间接来的).
    看到这里, 根源找到了, 也就是说transactionContext.shouldAutoClose()是要调用 SessionImpl类的shouldAutoClose方法, shouldAutoClose方法 又 有调用isAutoCloseSessionEnabled() && !isClosed(),最终看到是看isAutoCloseSessionEnabled方法里的autoCloseSessionEnabled属 性. 那这么个属性又是何时set的,源头在哪?

    可从下图的方法调用栈,看到了源头: ThreadLocalSessionContext类里的isAutoCloseEnabled方法,
通过"return true;"写死的!

这 里有一个不舒服的地方: SessionImpl实现了JDBCContext.Context接口, 虽说接口JDBCContext.Context继承自TransactionFactory.Context,但让SessionImpl这么早地就跟 具体JDBCXXXX绑定还是有些别扭, 有些畸形.

    对第二个条件的跟踪很是艰辛, 下面看第三个条件: !transactionContext.isClosed(), 应该说有了上面很是艰辛的分析后, 这里很自然地得知这里的第三个条件是调用了 SessionImpl 实现类的相应方法. (这里有个注意点: isClosed方法恰好也是SessionImplementor接口定义的,这样在SessionImpl(父类)里一石二鸟地对两个接口定义的方法 做了实现, 再往一想,是不是可以抽出一个接口closable,让SessionImplementor和TransactionFactory.Context两 个接口做下继承?)

1
0
分享到:
评论

相关推荐

    Hibernate_11session

    《深入理解Hibernate Session:从配置到实践》 Hibernate,作为Java领域中一款广泛使用的对象关系映射(ORM)框架,极大地简化了数据库操作。在Hibernate中,Session是连接应用程序和数据库的重要桥梁,它负责对象...

    hibernate的缓存机制和session对象的产生方式案例

    通过begin()开启事务,Hibernate会自动创建Session,然后在commit()或rollback()时关闭Session。这种方法简化了代码,但可能导致Session生命周期过长,增加内存压力。 总的来说,理解和熟练运用Hibernate的缓存机制...

    Hibernate教程20_关系映射案例三

    【标题】"Hibernate教程20_关系映射案例三"主要涵盖了在Hibernate框架中如何进行对象关系映射(ORM)的实践,特别是针对复杂关系的处理。在这个教程中,我们可能会学习到以下关键知识点: 1. **关系映射**:...

    hibernate中的相关组件的介绍

    尽管默认情况下文件名为`hibernate.cfg.xml`,但开发者可以根据需要自定义该文件的名称或存储位置。如果选择自定义配置文件的位置或名称,则需要通过`HibernateSessionFactory`类中的`CONFIG_FILE_LOCATION`属性来...

    hibernate5--2.数据持久化及事务

    Hibernate默认使用的是可重复读,避免了脏读和不可重复读的问题,但可能会出现幻读。根据具体应用场景,开发者可以调整隔离级别。 **4. 乐观锁和悲观锁** - **乐观锁**:假设并发冲突较少,只在更新时检查版本号等...

    Tomcat下配置Hibernate

    ### Tomcat下配置Hibernate知识点详解 #### 一、前言 在Java Web开发中,Tomcat作为一款轻量级的应用服务器被广泛使用。而在实际项目中,为了更好地管理数据库连接和进行对象关系映射(ORM),Hibernate框架因其...

    Hibernate笔记完整版

    3. Configuration:读取配置文件(默认为hibernate.cfg.xml)并生成SessionFactory,SessionFactory是线程安全的,负责创建Session实例。 4. Session:类似于JDBC中的Connection,是轻量级对象,不适用于并发环境,...

    第一个手写Hibernate

    "第一个手写Hibernate"项目旨在帮助开发者深入理解Hibernate的工作原理,通过手动编写相关代码,以实践的方式来学习和掌握Hibernate的核心概念。 **一、Hibernate简介** Hibernate是一个开源的ORM框架,它允许...

    详解Hibernate事务处理机制

    它通过设置连接的自动提交属性为`false`来开启事务,并在提交或回滚时恢复到默认状态。 ```java Session session = sf.openSession(); Transaction tx = session.beginTransaction(); // 执行业务逻辑 ...

    hibernate参考手册中文版

    - 自动提交事务:默认情况下,Hibernate会在每个操作后自动提交事务。 - **映射机制**: - 类到表的映射:使用注解或XML配置文件定义类与数据库表之间的映射关系。 - 属性到列的映射:指定类的属性如何映射到...

    Hibernate大总结/Hibernate面试题大全

    但在某些情况下,可能会分开使用 `hibernate.properties` 和 `hibernate.cfg.xml` 两个文件: - `hibernate.properties`: 主要用于配置数据连接、二级缓存、连接池等信息。 - `hibernate.cfg.xml`: 主要用于配置...

    hibernate示例

    - **懒加载**:默认情况下,关联的对象不会立即加载,只有在需要时才会加载,以提高性能。 - **级联操作**:通过`@OneToMany`、`@ManyToOne`等注解可以配置级联操作,如同时保存、删除关联的对象。 通过本示例,...

    struts.hibernate工作流程

    Struts和Hibernate是Java开发中两个非常重要的框架,它们分别专注于Web层和持久化层的管理。Struts作为MVC(Model-View-Controller)框架,主要负责处理HTTP请求,控制业务逻辑,以及与视图的交互。而Hibernate则是...

    hibernate-3.0.zip

    3. Transaction:事务管理是数据库操作的关键,Hibernate提供了集成的事务处理,通过Session的beginTransaction和commit/rollback方法来控制事务边界。 三、对象持久化 Hibernate通过映射文件(.hbm.xml)或注解将...

    hibernate_core_API

    Hibernate Core API是Java开发人员在使用Hibernate ORM框架时最常打交道的部分。它是Hibernate框架的核心组件,提供了对数据库操作的基本抽象和实现。版本3.3.1是该API的一个稳定版本,支持多种数据库交互功能,包括...

    hibernate3 api

    Hibernate 是一个开源的对象关系映射(ORM)框架,它允许Java开发者将数据库操作转化为对象间的操作,极大地简化了数据存取的过程。Hibernate3 API 手册是开发者在使用Hibernate进行数据库交互时的重要参考资料,它...

    hibernate 4.1 core API 英文版

    8. **第二级缓存**:除了默认的一级缓存(Session级别的缓存),Hibernate还支持二级缓存,用于存储多个Session共享的数据,提高性能。可以通过配置插件如EhCache实现。 9. **Transaction管理**:Hibernate提供了...

    hibernate.zip

    Hibernate使用Session的beginTransaction()、commit()和rollback()方法处理事务。事务的隔离级别和传播行为可以通过配置文件设置。 7. **缓存机制**: Hibernate内置了一级缓存(Session级别的)和二级缓存...

    Hibernate开发指南

    - **CriteriaQuery**: 提供了一个灵活的方式来构建查询条件。 - **HQL (Hibernate Query Language)**: 类似SQL,但面向对象的方式进行查询。 ##### 7. 数据关联 - **一对一关联**: - 单向一对一: 一方持有另...

    Hibernate 50个 英文面试题和答案

    第一级缓存是默认开启的,每个Session都有自己的缓存。第二级缓存是可选的,是跨Session共享的,可以使用第三方缓存提供者如Ehcache或Infinispan。 7. Hibernate支持哪些查询语言? Hibernate支持两种查询语言:...

Global site tag (gtag.js) - Google Analytics