Java 是冬眠';会话线程安全?

Java 是冬眠';会话线程安全?,java,hibernate,session,thread-safety,hibernate-session,Java,Hibernate,Session,Thread Safety,Hibernate Session,我需要知道,Hibernate的会话是否是线程安全的。但很明显,每个线程都附加了一个新会话来执行。但我的问题是,如果在一个线程中我更新了某个实体的某些值,那么在同一时间执行期间,这些值会反映在另一个线程中吗 我的问题是,当我从两个线程依次启动更新时,值会正确更新,但当我几乎同时启动更新时,它会失败 例如。 表的当前阶段 ID NAME MARKS ------- --------- -------- 1 John 54 我试着做以下几件事:

我需要知道,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会话和线程不会混合

您不应该同时使用来自多个线程的会话,我建议您只使用来自单个线程的会话。DB会话实现甚至不需要是ADSAFE

您还必须考虑在多线程中开始处理事务时发生的情况。事务绑定到当前线程。这很快就会让人头脑发热,您进入了实施者尚未测试其产品的领域


最后,生命太短暂,无法在沼泽中迷失方向。

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

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

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

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

  • getCurrentSession()
  • 对。它提供线程安全性,因为它将确保在会话不存在时为每个线程创建会话。事务和自动会话关闭附加到此

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

    会话对象被设计为由单个线程使用。在内部,会话使用许多非线程安全的数据结构,因此不可能实现线程安全

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

    话虽如此,拥有线程安全会话的需要是一种代码气味,表明数据访问层的设计存在缺陷


    . 你能告诉我如何在hibernate中达到隔离级别吗?除了上面提到的我正在使用事务将数据提交到数据库中。在你链接到的hibernate文档中引用了这个JavaDoc,但没有链接到它:可能会帮助其他人
    Session session = threadSafeSession.get();