单个hibernate会话中的多个事务(使用Spring)

时间:2012-11-23 14:31:26

标签: java spring hibernate transactions

是否可以使用Hibernate + Spring对以下内容进行建模。

  • 开放会话
  • 开始交易
  • 做一些工作
  • 提交
  • 开始交易
  • 更多工作
  • 提交
  • 关闭会话

我使用Spring TransactionTemplate来执行会话+事务生存期范围。

原因是有时我在业务流程中有几个阶段,并且我想在每个阶段完成后提交。但是我想继续使用相同的持久对象。如果每个事务都有一个单独的会话,那么我会得到瞬态/分离异常,因为原始会话已关闭。

这可能吗?

2 个答案:

答案 0 :(得分:6)

是的,Hibernate的会话可以开始并提交多个事务。你需要做的是在某个地方存储开放会话,然后重复使用它。注意,Session不是一个线程安全的对象,但是如果你确定它不会出现并发问题,你需要的只是使用TransactionSynchronizationUtils将会话绑定到线程资源然后解除绑定如果需要,您可以找到一个示例here,或者您可以查看OSIV及其标准实现。

这是一个非常复杂的事情,它更容易,因此您希望立即关闭会话并且不重复使用它,因为它可能会带来麻烦:

  • 缓存中的对象不会自动逐出,因此会话的大小会增加,直到OutOfMemory。
  • 会话内部的对象不会被刷新,除非它们是脏的,因此另一个用户更改对象的机会越来越大。确保只有一个用户可以更改可写对象。
  • 如果在其中一个步骤中发生某些异常,则必须确保关闭会话。在Session内部发生异常后,此对象不可重用。
  • 如果事务已回滚,则会话被Spring清除,因此所有对象都将被分离。如果至少有一个事务被回滚,请确保丢弃所有内容。

答案 1 :(得分:2)

您可以使用OpenSessionInView模式实现此目的。 Spring提供了一个javax.servlet.Filter实现,如果你在servlet环境中工作,你可以使用它(问题没有这么说)。这将确保您的Hibernate会话在请求期间保持打开,而不仅仅是针对单个事务。

class上的Javadoc非常全面,可能是一个很好的起点。