-
大家都说Hibernate中的session是线程不安全的,为什么呢?5
文档都说Hibernate中的session是线程不安全的,为什么呢?
是不是session里面含有什么数据是公共的?或者session里面的操作没有加synchronized关键字
为什么将session和ThreadLocal绑定之后,就线程安全的了?
既然从 SessionFactory.openSession() 获取 Session 不是单例模式,也就是每次获取 Session都是不同(为每个线程分配一个session对象)的,那么为什么会出现多个线程同时访问同一个Session的线程不安全问题呢?
2013年1月30日 12:31
2个答案 按时间排序 按投票排序
-
取自http://www.javamex.com/tutorials/servlets/session_synchronization.shtml,讲得很明白:
Session synchronization issues
It's quite feasible that different threads will access the same HttpSession object. This can happen simultaneously (a client makes two simultaneous connections with the same session ID). Or even with serial requests from a client, it's quite likely that a different thread will service each call (since servers generally hand out requests arbitrarily to the next available thread from a "pool" of threads). So in either case, we need to be sure that the different threads see a consistent view of a given HttpSession object.
(Remember: synchronization isn't just about the problem of concurrent access; it's also about the problem of data visibility between different threads. You may wish to see the section on variable synchronization for more information.)
Calls to getAttribute() and setAttribute() should have the same synchronization semantics as accessing a synchronized hash map. This means that:
concurrent calls to getAttribute() and setAttribute() are thread-safe in the sense that they will not leave the internal data structure in a "broken" state...
...unless your Servlet runner has a synchronization bug, of course;
if you want to combine multiple sets/gets into an atomic operation, then you need explicit synchronization.
The last point is the one that people seem to either forget or not appreciate. Let's say you want to associate with a session a user ID plus some other properties that are dependent on that user ID: user name, real name etc. If we set these as individual properties on the session, then we need synchronization:
HttpSession sess = req.getSession(true);
synchronized (sess) {
sess.setAttribute("USERID", id);
sess.setAttribute("USERNAME", username);
...
}
Without the synchronization, there is a risk that another thread could read, say, the user ID but a null user name.
As of Java 5, an alternative, often preferable, strategy is to use a mutable object to combine the properties. Remember that an immutable object is one with final fields. So if we wrap our user data inside a DBUser object defined with final fields as follows1:
public class DBUser {
private final int id;
private final String username;
private final String firstName;
...
public static DBUser retrieve(Stirng username) {
... retrieve data from DB ...
return new DBUser(id, ...);
}
private DBUser(int id, ...) {
// set values on all the final fields
this.id = id;
...
}
}
Then as of Java 5, it is completely safe to do the following, without synchronization:
DBUser user = DBUser.retrieve(username);
HttpSession sess = req.getSession(true);
sess.setAttribute("USER", user);
A special requirement of the JVM is that, if the object is visible at all to another thread, then the values of all its final fields will be visible. So there is no chance of the other thread "seeing" the user object in an inconsistent state, as would be the case if all of the fields were set (without synchronization) as individual attributes on the HttpSession object.2013年1月30日 23:04
-
你可以参考
http://aixiangct.blog.163.com/blog/static/9152246120113652732924/
和
http://fengbin2005.iteye.com/blog/11604282013年1月30日 13:24
相关推荐
总的来说,Hibernate中Session的管理是保证多线程环境下数据一致性的重要环节。ThreadLocal提供了一种有效且便捷的解决方案,但同时也需要注意其内存消耗和内存泄漏的风险,特别是在长生命周期的线程中。理解并选择...
总的来说,理解并正确使用“当前线程中的Session”是Hibernate开发中的重要一环。它可以帮助我们更高效、安全地处理数据库事务,确保数据的完整性和一致性。在实际项目中,根据应用的需求和环境选择合适的事务管理...
1. **非线程安全**:由于`Session`不是线程安全的,因此在多线程环境中,每个线程都应有自己的`Session`实例,以避免数据存取的混乱。 2. **轻量级**:`Session`的创建和销毁相对快速,降低了资源的消耗。 3. **第一...
在Java的持久化框架中,Hibernate是一个非常重要的组件,它为开发者提供了强大的对象关系映射(ORM)功能,使得在Java应用中操作数据库变得更加简单。本文将深入探讨Hibernate中的核心概念——Session管理。 首先,...
在Hibernate中,`SessionFactory`是核心组件之一,它是线程安全的,用于创建`Session`对象。`SessionFactory`通常在应用启动时创建一次,然后在整个应用生命周期中复用。创建`SessionFactory`需要通过读取Hibernate...
Hibernate的Session接口是Java应用程序与Hibernate之间主要的运行时交互接口,它提供了对持久化对象的创建、读取和删除操作。Session的概念是基于对象的状态管理和数据库事务的,它的生命周期通常与一个物理事务绑定...
在 Hibernate 中,每个线程都需要一个 Session 对象来与数据库交互。如果未绑定 Session 到线程, Hibernate 将无法正确地执行数据库操作。 解决方案 解决该错误的方法很简单,只需在相应的 manager 实现类中添加 ...
在Java的持久化框架中,Hibernate是一个非常重要的存在,它为开发者提供了强大的对象关系映射(ORM)功能,简化了数据库操作。本示例将深入探讨Hibernate Session的生命周期及其使用,帮助你更好地理解和运用这个...
在Java的持久化框架Hibernate中,Session对象是与数据库交互的核心组件,它负责管理对象的持久状态。在处理大量数据或者长时间运行的事务时,合理地管理Session的生命周期至关重要,这就涉及到了Hibernate的Session...
在Java的持久层框架Hibernate中,SessionFactory是核心组件之一,它是线程安全的,负责创建Session对象,每个Session对应于数据库的一次会话。配置SessionFactory主要是通过Hibernate的配置文件(通常为hibernate....
### Hibernate的核心接口——Session详解 #### 一、Session简述 **1. Session概念** - **定义**: Session 是 Hibernate 框架中最常用的接口之一,它又被称为持久化管理器。Session 负责所有与数据库交互的工作,...
5. **线程安全**:`Session`不是线程安全的,因此在多线程环境中,包装类可能需要考虑如何正确管理和关闭`Session`实例,避免并发问题。 6. **简化API**:根据项目需求,包装类可以提供一些简洁的API,比如`...
通过以上介绍,我们可以看到Hibernate Session在数据库操作中的核心地位,正确理解和使用Session是掌握Hibernate的关键。实践中的具体应用需要结合项目需求,灵活运用这些知识,以实现高效、稳定的数据库访问。
总的来说,`Session`在Hibernate中扮演着至关重要的角色,`delete()`方法是它实现对象持久化操作的一部分,正确理解和使用这些方法对于高效地操作数据库至关重要。理解`Session`的工作原理,以及与`SessionFactory`...
Hibernate是一款开源的对象关系映射(Object/Relational Mapping,...整个文档是一个综合性的Hibernate使用指南,它从理论到实践都有所涵盖,对于任何想要深入学习和使用Hibernate框架的Java开发者来说都是宝贵的资源。
- `SessionFactory`是线程安全的,整个应用只需要一个,它负责创建`Session`实例,每个数据库操作需要一个新的`Session`。 - `Session`是短生命周期的,每个数据库操作开始时创建,完成后关闭,避免长时间持有导致...
本篇文章将深入探讨在使用Hibernate时可能会遇到的线程同步问题,以及 Hibernate 中的 session.get() 和 session.load() 方法的异同。 一、Hibernate的并发控制 在多线程环境下,多个线程同时访问和修改数据库记录...
关于 Hibernate 中 Session 的关闭实例解析 Hibernate 是一个流行的 Java 持久层框架,它提供了许多强大功能来管理数据库交互。Session 是 Hibernate 中的一种基本概念,它扮演着关键角色来管理数据库交互。本文将...
本篇将详细讲解如何在Hibernate中手动获取Session,以及涉及到的相关配置和连接管理。 首先,理解Hibernate的核心组件——Session。Session是Hibernate中的工作单元,它是与数据库交互的主要接口,负责保存、更新和...