您可以在一个 Hibernate 会话中进行多个事务吗?

新手上路,请多包涵

您可以在一个 Hibernate 会话中进行多个事务吗?

我不清楚这是否是可取的。在我的代码中,我有一个长时间运行的线程并从阻塞队列中获取项目,这取决于队列中的内容,它可能需要创建并保存一个休眠对象,或者它可能不需要执行任何操作。

每个项目都是不同的,因此如果项目 1 被保存而项目 2 无法保存,无论出于何种原因我不想阻止项目 1 被添加到数据库中。

所以最简单的方法就是为每个需要创建的item创建一个新的session,open transaction,save new object,commit transaction,close session

然而,这意味着为每个项目创建一个新会话,这似乎违背了 Hibernates 自己的建议,即不执行 Session Per Request Pattern。所以我的替代方案是在线程中创建一个会话,然后在需要创建新对象时根据需要打开并提交一个新事务。但我没有看到这种方法的例子,我不确定它是否真的有效。

原文由 Paul Taylor 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 430
2 个回答

如果您运行本地事务,则每个请求一个会话模式对每个会话使用一个 JDBC 连接。对于 JTA,连接在每个语句后被主动释放,只是为了下一个语句重新获取。

Hibernate 事务 API 将开始/提交/回滚委托给本地事务的 JDBC 连接和 JTA 的关联 UserTransaction。因此,您可以在同一个 Hibernate Session 上运行多个事务,但有一个问题。一旦抛出异常,您就不能再重用该会话。

我的建议是分而治之。只需拆分所有项目,为每个项目构建一个 Command 对象并将它们发送到 ExecutorService#invokeAll 。使用返回的 List 迭代并调用 Future#get() 以确保原始线程在所有批处理作业完成后等待。

ExecutorService 将确保您同时运行所有命令,并且每个命令都应该使用一个服务,该服务使用自己的 @Transaction 。因为事务是线程绑定的,所以所有 的批处理作业都是独立运行的

原文由 Vlad Mihalcea 发布,翻译遵循 CC BY-SA 4.0 许可协议

显然,你可以。休眠会话或多或少是一个数据库连接和数据库对象的缓存。并且您可以在单个数据库连接中有多个连续的事务。更多,当你使用连接池时,连接不是关闭而是被回收。

你是否应该重用会话中的对象是一个问题。如果有很好的机会,但您可以重用先前事务已放入会话中的对象,则您应该为多个事务保留一个会话。但是如果一个对象一旦被提交,它就永远不会被重新使用,那么最好关闭会话并重新打开一个新的会话,或者干脆清除它。

怎么做 :

如果你有一个 Session 对象,你可以创建交易:

 Transaction transaction;
transaction = session.beginTransaction();
... (operations in the context of transaction)
transaction.commit();
... (other commands outside of any transaction)
transaction = session.beginTransaction();
... (and so on and so forth ...)

原文由 Serge Ballesta 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题