你能在一个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会话中拥有多个交易吗?的主要内容,如果未能解决你的问题,请参考以下文章