hibernate session 事务

 

1.session 生命周期

session并不同于连接,一个连接可被多个会话使用,并且一个连接同时只能属于一个会话,会话直到消亡,会一直持有该connection,因些系统设计时对于何时释放连接,是很重要的。

会话的默认的生命周期始于当前线程开始数据库操作,会附属于当前线程中, 对于session的终结,根据连接释放模式来确定,

 

 

 

2.事务 生命周期

事务的生命周期由可人为控制,对于spring使用AOP方式来管理事务时,使用通过对方法进行拦截进行事务管理这种方式。对于有多个事务声明的方法之间调用,会牵扯到事务的传递方式

注:对于理解来说一个声明事务的方法执行完就是事务的结束,但对于使用了Open Session in View也使用声明事务的方法,会造成事务边界扩展到VIEW层。

3.session同事务的关系

理论上,一个session 可有多个事务,人为的方式可以实现之,但对于现在大部分使用了spring事务声明管理方式来说,一般的一个会话只使用一个事务。

4.操作单元的选择

别用 session-per-operation 这种反模式了,也就是说,在单个线程中, 不要因为一次简单的数据库调用,就打开和关闭一次 Session!数据库事务也是如此。

在多用户的 client/server 应用程序中,最常用的模式是 每个请求一个会话(session-per-request)。 在这种模式下,来自客户端的请求被发送到服务器端(即 Hibernate 持久化层运行的地方),一个新的 Hibernate Session 被打开,并且执行这个操作单元中所有的数据库操作。一旦操作完成(同时对客户端的响应也准备就绪),session 被同步,然后关闭。你也可以使用单 个数据库事务来处理客户端请求,在你打开 Session 之后启动事务,在你关闭 Session 之前提交事务。会话和请求之间的关系是一对一的关系,这种模式对 于大多数应用程序来说是很棒的。 

Hibernate 内置了对"当前 session(current session)" 的管理,用于简化此模式。你要做的一切就是在服务器端要处理请求的时候,开启事务,在响应发送给客户之前结束事务。你可以用任何方式来完成这一操作,通常的方案有 ServletFilter,在 service 方法中进行 pointcut 的 AOP 拦截器,或者 proxy/interception 容器。

 

一般来说使用session-per-request很适合当前的需要。如我们使用session-per-operation这种模式的话会增加系统性能开销,即使session的创建的开销并不大,但也不提倡这种做法,对于长对话(session-per-conversation)也并不是我们的选择,虽然session-per-conversation对对像状态不需要很麻烦的维护,但使用对象实例的版本检查检测到并发修改则抛出异常,由开发人员来处理的方式并不是好的选择。

 

 

连接释放模式:

通过 org.hibernate.ConnectionReleaseMode 的不同枚举值来使用不用的释放模式:

ON_CLOSE:基本上就是上面提到的老式行为。Hibernate session 在第一次需要进行 JDBC 操作的时候获取连接,然后持有它,直到 session 关闭。 

 

AFTER_TRANSACTION:在 org.hibernate.Transaction 结束后释放连接。 

 

AFTER_STATEMENT(也被称做积极释放):在每一条语句被执行后就释放连接。但假若语句留下了与 session 相关的资源,那就不会被释放。目前唯一的这种情形就是使用 org.hibernate.ScrollableResults。 

 

hibernate.connection.release_mode 配置参数用来指定使用哪一种释放模式。可能的值有: 

 

auto(默认):这一选择把释放模式委派给 org.hibernate.transaction.TransactionFactory.getDefaultReleaseMode() 方法。对 JTATransactionFactory 来说,它会返回 ConnectionReleaseMode.AFTER_STATEMENT;对 JDBCTransactionFactory 来说,则是ConnectionReleaseMode.AFTER_TRANSACTION。很少需要修改这一默认行为,因为假若设置不当,就会带来 bug,或者给用户代码带来误导。 

 

on_close:使用 ConnectionReleaseMode.ON_CLOSE。这种方式是为了向下兼容的,但是已经完全不被鼓励使用了。 

 

after_transaction:使用 ConnectionReleaseMode.AFTER_TRANSACTION。这一设置不应该在 JTA 环境下使用。也要注意,使用 ConnectionReleaseMode.AFTER_TRANSACTION 的时候,假若session 处于 auto-commit 状态,连接会像 AFTER_STATEMENT 那样被释放。 

 

after_statement:使用 ConnectionReleaseMode.AFTER_STATEMENT。除此之外,会查询配置的 ConnectionProvider,是否它支持这一设置(supportsAggressiveRelease())。假若不支持,释放模式会被设置为 ConnectionReleaseMode.AFTER_TRANSACTION。只有在你每次调用 ConnectionProvider.getConnection() 获取底层 JDBC 连接的时候,都可以确信获得同一个连接的时候,这一设置才是安全的;或者在 auto-commit 环境中,你可以不管是否每次都获得同一个连接的时候,这才是安全的。 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值