Hibernate的会话线程安全吗?

我需要知道,Hibernate的会话是否是线程安全的。 但很明显,每个线程都会附加一个新会话来执行。 但我的问题是,如果在一个线程中我更新了一个实体的某个值,那么在同一时间执行期间会反映在其他线程中吗?

我的问题是当我从两个线程顺序触发更新时,值正确更新但是当我几乎完全触发更新时它就失败了。

例如。 现阶段的表。

ID NAME MARKS ------- --------- -------- 1 John 54 

我想做的是:

 Student student = session.load(Student.class, 1); student.setMarks(student.getMarks() + 1); session.update(student); session.close(); 

当我尝试在循环中运行上面的代码(例如10)时,表“student”中的“marks”值被正确更新,即值更新为64,这是正确的。

但是当我尝试在线程环境中运行相同的代码时,它会产生错误的结果。

并不意味着实现者是线程安全的。 相反,每个线程/事务应从SessionFactory获取自己的实例。

即使考虑到这一点,您的行为可能仍然不是您所期望的,因为交易发挥作用。 您必须设置适当的事务隔离级别 。 请参阅配置指南 hibernate.connection.isolation属性。

Hibernate会话和线程不混合。

您不应该同时使用来自多个线程的会话,我建议您仅使用单个线程中的会话。 数据库会话实现甚至不需要是安全的。

当你开始在多个线程中做事时,你还必须考虑事务会发生什么。 事务与当前线程相关联。 这变得很快,你进入实施者没有测试过产品的区域。

到最后,生命太短暂,不能迷失在沼泽中。

Hibernate会话不是线程安全的。 使用TheadLocal类为每个线程创建会话: –

  private static ThreadLocal threadSafeSession = new ThreadLocal() { protected Session initialValue(){ return sf.openSession(); } }; 

在你的方法中,每个线程的get会话为: –

 Session session = threadSafeSession.get(); 

这取决于您创建会话的方式。

可以在hibernate中以两种方式创建会话。

  1. 的getCurrentSession()

是。 它提供了线程安全性,因为它确保如果会话不存在,它将为每个线程创建一个会话。 事务和自动会话关闭附加到此。

  1. 的openSession()

这不是线程安全的。 开发人员手动需要管理事务和会话刷新和关闭操作。

Session对象旨在由单个线程使用。 在内部,Session使用许多非线程安全的数据结构,因此不可能使其成为线程安全的。

此外,您甚至不需要使用线程安全的Session。 如果您的用例是共享高速缓存的实体,那么您应该使用二级高速缓存,它是线程安全的,可以在集群环境中使用。

话虽如此,对线程安全会话的需求是代码气味,表明数据访问层设计存在缺陷。