Java Hibernate 的会话线程安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3777794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 04:52:28  来源:igfitidea点击:

Is Hibernate's session thread safe?

javahibernatesessionthread-safetyhibernate-session

提问by M.J.

I need to know, whether the Hibernate's session is thread safe or not. But obvious a new session is attached to every thread for execution. But my question is if in one thread I have updated some value of an entity, so will that be reflected in other thread during same time execution?

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

My problem is when I fire update from two threads sequentially, the value is updated properly but when I fire the update almost altogether then it fails.

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

for eg. current stage of table.

例如。表的当前阶段。

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

I am trying to do follwing :

我正在尝试执行以下操作:

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

When I try to run the above code in loop say 10, then value of "marks" in table "student" is properly updated i.e. the value gets updated to 64 which is proper.

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

But when I try to run the same code in threaded environment, it gives bad results.

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

采纳答案by Bozho

It is not intended that implementors be threadsafe. Instead each thread/transaction should obtain its own instance from a SessionFactory.

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

Even with this in mind, your behaviour might still not be what you expect, because transactions come into play. You will have to set a proper transaction isolation level. See the configuration guide, hibernate.connection.isolationproperty.

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

回答by Peter Tillemans

Hibernate session and threads do not mix.

Hibernate 会话和线程不混合。

You should not use a session from multiple threads at once, and I recommend you only use a session from a single thread. DB session implementations are not even required to be theadsafe.

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

You also must consider what happens to the transactions when you start doing things in multiple threads. Transactions are tied to the current thread. This becomes quickly mindblowing and you enter areas where the implementers have not tested their products.

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

In the end life is too short to get lost in that swamp.

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

回答by Goyal Vicky

Hibernate sessions are not thread safe. Use TheadLocal class to create sessions for each thread:-

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

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

In your method get session for each thread as:-

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

Session session = threadSafeSession.get();

回答by Sumanth Varada

It depends on how you are creating a session.

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

Session can be created in two ways in hibernate.

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

  1. getCurrentSession()
  1. 获取当前会话()

Yes. It offers thread safety as it'll ensure that it'll create a session for each thread if session not exist. transaction and automatic session closing is attached to this.

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

  1. openSession()
  1. 打开会话()

It's not thread safe. developer manually needs to manage transactions and session flush and close operations.

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

回答by Vicky

The Session object was designed to be used by a single thread. Internally, the Session uses many non-thread-safe data structures so it's impossible to make it thread-safe.

More, you shouldn't even need to use a thread-safe Session . If your use case is to share the cached entities, then you should use the second-level cache instead which is thread-safe and can be used in a clustered environment.

That being said, the need for having a thread-safe Session is a code smell indicating a flaw in the design of the data access layer.

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

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

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