12

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

  • 公开课
  • 开始交易
  • 做一些工作
  • 犯罪
  • 开始交易
  • 更多的工作
  • 犯罪
  • 关闭会话

我使用 Spring TransactionTemplate,它同时执行会话 + 事务生命周期范围。

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

这可能吗?

4

2 回答 2

6

是的,Hibernate 的 Sessions 可以开始并提交多个事务。您需要做的是将打开的会话存储在某处,然后重用它。请注意, Session 不是线程安全对象,但如果您确定它不会有并发问题,您只需将会TransactionSynchronizationUtils话绑定到线程资源,然后在需要时取消绑定,您可以在这里找到一个示例,或者您可以查看 OSIV 及其标准实现。

这是一个非常复杂的事情,它会容易得多,因此最好立即关闭会话并且不要重用它,因为它可能会带来麻烦:

  • 缓存内的对象不会自动被驱逐,因此您的 Session 将增长到 OutOfMemory。
  • 会话内部的对象不会被刷新,除非它们是脏的,因此对象被另一个用户更改的机会越来越大。确保只有一个用户会更改可写对象。
  • 如果在其中一个步骤中发生异常,您必须确保关闭会话。在 Session 内部发生异常后,该对象不可重用。
  • 如果事务回滚,则 Spring 会清除会话,因此您的所有对象都将分离。如果至少有一个事务被回滚,请确保丢弃所有内容。
于 2012-11-23T16:35:22.130 回答
2

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

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

于 2012-11-23T16:30:21.773 回答