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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你能在一个Hibernate会话中拥有多个交易吗?相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

答案

如果运行本地事务,则每个请求的会话模式会在每个会话中使用一个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会话上运行多个事务,但是有一个问题。抛出异常后,您将无法再重用该Session。

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

ExecutorService将确保您同时运行所有命令,并且每个Command应使用使用其自己的@Transaction的服务。因为事务是线程绑定的,所以你将拥有所有batch jobs run in isolation

另一答案

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

是否应该重新使用会话中的对象。如果有很好的机会,但您可以重用先前事务已放入会话的对象,则应为多个事务保留一个会话。但是,如果一旦提交了一个对象,它将永远不会被重用,关闭会话并重新打开一个新会话或者只是清除它肯定会更好。

怎么做 :

如果您有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 ...)
另一答案

来自hibernates文档

“会话是一种廉价的,非线程安全的对象,应该使用一次,然后丢弃用于:单个请求,对话或单个工作单元。会话将不会获得JDBC连接或数据源,除非它是在使用之前它不会消耗任何资源。“

因此,如果您一次又一次地创建会话,则不会给系统带来太大负担。如果你继续会话的时间太长,可能会产生问题,因为会话不是线程安全的。在我看来,最简单的解决方案是最好的“所以最简单的方法是为每个需要创建的项目创建一个新的会话,打开事务,保存新对象,提交事务,关闭会话“

顺便说一句,如果你创建任何事情的单一记录,你不需要太多的交易。创建单个记录本质上是“全部或全部”我们使用事务的东西

另一答案

简短的回答是肯定的,你可以使用相同的会话进行交易。看一下org.hibernate.Transaction。,它需要管理事务的方法。

另一答案
package hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
class Tester {
public static void main(String[] args) {
    SessionFactory sf = new org.hibernate.cfg.Configuration().configure().buildSessionFactory(new StandardServiceRegistryBuilder().configure().build());
    Session session = sf.openSession();
    session.beginTransaction();
        Student student = new Student();
    student.setName("Mohammad Faizan");
    student.setRollNo(1309114040);
        session.save(student);
    session.getTransaction().commit();
    session.getTransaction().begin();
    session.load(Student.class,23);
    student.setName("New Name");
    student.setRollNo(123);
    session.update(student);
    session.getTransaction().commit();
    session.close();
  }
}

以上是关于你能在一个Hibernate会话中拥有多个交易吗?的主要内容,如果未能解决你的问题,请参考以下文章

Git:你能在master改变后更新分支吗?

你能在不同的线程上调用相同的方法吗?

你能拥有多个ajax吗?

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

你能在 ClutterStage 中嵌入 GtkWidgets 吗?

你能在三元中有一个返回和一个公式吗?