你能在一个Hibernate会话中拥有多个交易吗?
我不清楚这是否是可取的。在我的代码中,我有一个长时间运行的线程并从阻塞队列中获取项目,具体取决于队列中的内容,它可能需要创建和保存hibernate对象,或者它可能不需要执行任何操作。
每个项目都是不同的,所以如果项目1被保存,项目2无法保存我不想要的任何原因,以防止项目1被添加到数据库中。
所以最简单的方法是为需要创建的每个项创建一个新会话,打开事务,保存新对象,提交事务,关闭会话
然而,这意味着为每个项目创建了一个新会话,这似乎违反了Hibernates自己的建议,即不执行会话每个请求模式。所以我的替代方案是在线程中创建一个会话,然后在需要创建新对象时根据需要打开并提交新事务。但是,我没有看到这种方法的例子,我不确定它是否真的有用。
答案 0 :(得分:26)
如果运行本地事务,则每个会话的会话模式会在每个会话中使用一个JDBC连接。对于JTA,只有在下一个语句重新获取时才会在每个语句之后积极地释放连接。
Hibernate transaction API delegates the begin/commit/rollback to the JDBC Connection for local transactions and to the associated UserTransaction for JTA。因此,您可以在同一个Hibernate会话上运行多个事务,但是有一个问题。抛出异常后,您将无法再重用该会话。
我的建议是分而治之。只需拆分所有项目,为每个项目构建一个Command对象,然后将它们发送到ExecutorService#invokeAll
。使用返回的List迭代并调用Future#get()
以确保原始线程在所有批处理作业完成后等待。
ExecutorService
将确保您同时运行所有命令,并且每个Command应使用使用其自己的@Transaction
的服务。由于事务是线程绑定的,因此您将拥有所有batch jobs run in isolation。
答案 1 :(得分:12)
是否应该重新使用会话中的对象。如果有很好的机会,但您可以重用先前事务已放入会话的对象,则应为多个事务保留一个会话。但是,如果一旦提交了一个对象,它将永远不会被重用,关闭会话并重新打开一个新会话或者只是清除它肯定会更好。
怎么做:
如果您有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 ...)
答案 2 :(得分:3)
来自hibernates文档
"会话是一种廉价的非线程安全对象,应该使用一次然后丢弃,用于:单个请求,对话或单个工作单元。除非需要,否则会话将不会获取JDBC连接或数据源。在使用之前,它不会消耗任何资源。"
因此,如果您一次又一次地创建会话,则不会给系统带来太大负担。如果你继续会话的时间太长,可能会产生问题,因为会话不是线程安全的。在我看来,最简单的解决方案是最好的"所以最简单的方法是为每个需要创建的项目创建一个新会话,打开事务,保存新对象,提交事务,关闭会话"
顺便说一句,如果你创建任何事情的单一记录,你就不需要太多的交易。创造单一记录本身就是"全部或全部没有#34;我们使用交易的东西
答案 3 :(得分:0)
简短回答是肯定的,您可以使用相同的会话进行交易。看看org.hibernate.Transaction。,它需要管理事务的方法。
答案 4 :(得分:0)
a=matrix([[1,2,3],
[8,2,9],
[1,8,7]])
row = [1,2,3]
col = [[1,2]
[1,3]
[2,3]]