【问题标题】:Hibernate Session and thread safety休眠会话和线程安全
【发布时间】:2015-04-11 10:06:46
【问题描述】:

我试图理解“休眠会话不是线程安全的”的含义。我已经知道的(如果我错了,请纠正我):

  1. 非 JTA 环境中的会话保存在 Thread Local 中。所以它绑定到当前线程。
  2. 在新线程中调用 getCurrentSession() 会将新会话与其自己的本地线程相关联。
  3. 假设我们在 2 个线程(T1、T2)之间共享一个实体,在 T1 中加载并在 T2 中使用,我们可能会遇到延迟加载等问题,因为 T1 和 T2 中的会话不同。

这解释了在不同会话之间共享实体时可能出现的问题。

我无法理解的是当 Session 在 2 个或更多线程之间共享时可能出现的问题。我知道 Session 中的方法不是线程安全的,并且可能导致竞争条件等,但不清楚如何?如果有人可以举例说明或列出一个或多个场景进行澄清,我将不胜感激。

提前致谢

【问题讨论】:

    标签: java multithreading hibernate race-condition hibernate-session


    【解决方案1】:

    Java memory model 对以下方面有非常严格的规定:

    • 线程间内存可见性
    • 线程操作重新排序

    Session 对象不是线程安全的,这意味着它永远不会被多个线程访问。为此,它不使用线程安全机制:

    • 没有互斥体
    • 没有易失性读取
    • 没有同步

    如果您在两个线程之间共享 Hibernate Session,则一个线程的更改可能对其他线程不可见(没有适当的同步或易失性读取)。

    每个 Hibernate Session 都有一个关联的 JDBC 连接(即使 JTA 激进的发布最终会为一个 JTA 事务数据源发出的所有语句重用相同的 JDBC 连接)。一个 JDBC 连接不应该被两个线程访问,因为每个线程应该绑定到一个且只有一个数据库事务。

    【讨论】:

    • 谢谢弗拉德。是否有一个例子或一个应用场景来说明事情是如何出错的?这将进一步帮助我。
    • 我没有任何示例,但您可以自己轻松尝试。
    • 我在主线程和其他线程中使用 sessionFactory.openSession(),在主线程中创建会话,我打开一个事务,在本机查询上调用 executeUpdate 并关闭事务,一切正常正好。怎么会?在一个线程中创建会话并在具有相同会话的另一个线程中执行本机查询
    猜你喜欢
    • 2013-12-07
    • 1970-01-01
    • 2012-05-29
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 1970-01-01
    相关资源
    最近更新 更多