20

我需要知道 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,这是正确的。

但是当我尝试在线程环境中运行相同的代码时,结果很糟糕。

4

4 回答 4

24

实现者并不是线程安全的。相反,每个线程/事务都应该从 SessionFactory 获得自己的实例。

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

于 2010-09-23T11:29:32.187 回答
20

休眠会话和线程不混合。

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

当您开始在多个线程中执行操作时,您还必须考虑事务会发生什么。事务与当前线程相关联。这很快就会变得令人难以置信,并且您进入了实施者尚未测试其产品的区域。

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

于 2010-09-23T11:32:53.533 回答
4

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

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

在您的方法中为每个线程获取会话:-

Session session = threadSafeSession.get();
于 2015-08-09T07:04:06.627 回答
4

这取决于您如何创建会话。

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

  1. 获取当前会话()

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

  1. 打开会话()

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

于 2017-03-11T20:26:08.073 回答