你能在一个Hibernate会话中拥有多个交易吗?

Pau*_*lor 24 java database session hibernate transactions

你能在一个Hibernate会话中拥有多个交易吗?

我不清楚这是否是可取的.在我的代码中,我有一个长时间运行的线程并从阻塞队列中获取项目,具体取决于队列中的内容,它可能需要创建和保存一个hibernate对象,或者它可能不需要做任何事情.

每个项目都是不同的,所以如果项目1被保存,项目2无法保存我不想要的任何原因,以防止项目1被添加到数据库.

因此,最简单的方法是为每个需要创建的项目创建新会话,打开事务,保存新对象,提交事务,关闭会话

但是,这意味着为每个项目创建了一个新会话,这似乎违反了Hibernates自己的建议,即不执行会话每个请求模式.所以我的选择是在线程中创建一个会话,然后在需要创建新对象时根据需要打开并提交新事务.但我没有看到这种方法的例子,我不确定它是否真的有效.

Vla*_*cea 29

如果运行本地事务,则每个请求的会话模式会在每个会话中使用一个JDBC连接.对于JTA,只有在下一个语句重新获取时才会在每个语句之后积极地释放连接.

Hibernate事务API代表了开始/提交/回滚到JDBC连接本地交易,并为JTA相关的UserTransaction.因此,您可以在同一个Hibernate会话上运行多个事务,但是有一个问题.抛出异常后,您将无法再重用该Session.

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

ExecutorService将确保您同时运行所有命令,并且每个Command应使用使用自己的命令@Transaction.由于事务是线程绑定的,因此您将使所有批处理作业独立运行.

  • 当然.这很简单.同步状态失败的[后写缓存](https://vladmihalcea.com/a-beginners-guide-to-cache-synchronization-strategies/)无法重复使用,因为它可能已被部分刷新,即使您重用它总是会导致抛出相同的异常(例如约束违规). (2认同)

Ser*_*sta 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 ...)
Run Code Online (Sandbox Code Playgroud)