hibernate中session线程安全的实现

在hibernate中session是使用ThreadLocal实现线程安全的。

ThreadLocal并不是一个Thread,而是一个线程副本,ThreadLocal为每个使用该变量的线程提供一个变量副本,线程修改自己的变量副本不会影响其他线程的变量副本

ThreadLocal有四个方法:

set():设置当前线程的局部变量的值

get():获取当前线程的局部变量的值

remove():将当前线程局部变量的值删除,此方法不必显示的调用,因为局部变量自有垃圾回收器去清理

initialValue():返回该局部变量的初始值,只有在线程第一次调用get,set方法时,此方法才会执行

ThreadLocal源码如下:

     
    public class ThreadLocal {
                /*这个集合中以当前线程对象作为键,值就是该线程对象的变量副本的值,也就是
                 * session
                 */
    		Map map = Collections.synchronizedMap(new HashMap());
    		public Object get(){
    			Thread currentThread = Thread.currentThread();
    			Object o = map.get(currentThread);
    			if(o == null && !map.containsKey(currentThread)){
    				o = initialValue();
    				map.put(currentThread, o);
    			}
    			return o;
    		}
    
    		public void set(Object newValue){
    			map.put(Thread.currentThread(), newValue);
    		}
    
    		public Object initialValue() {
    			return null;
    		}
    	}

hibernate中的getCurrentSession()的底层代码如下:

public class CurrentSession {

		public static final ThreadLocal session = new ThreadLocal();

		public static final SessionFactory sf;
		static {
			sf = new Configuration().configure().buildSessionFactory();
		}

		public Session getCurrentSession(){
			Session s = (Session) session.get();
			if(s == null){
				s = sf.openSession();
				session.set(s);
			}
			return s;
		}

	}

总结:要想让多线程实现对共享资源的操纵,就需要对它进行同步处理,这不是一件容易的事,不仅会降低程序性能,还要小心死锁的产生,而ThreadLocal模式,直接让每一个线程都具有自己的一个session,他仅仅操作自己的session不会影响其它线程的session,因此也就不需要进行同步处理

时间: 2024-12-20 15:30:12

hibernate中session线程安全的实现的相关文章

Hibernate中Session与本地线程绑定

------------------siwuxie095 Hibernate 中 Session 与本地线程绑定 1.Session 类似于 JDBC 的连接 Connection 2.Session 对象是单线程对象,只能自己使用,不能共用 将 Session 与本地线程绑定,保证 Session 对象绝对是一个单线程对象 3.Hibernate 帮助我们实现了 Session 与本地线程绑定(底层是 ThreadLocal) 4.获取与本地线程绑定的 Session (1)在 Hiberna

hibernate中session的获取使用以及其他注意事项

hibernate中session的获取使用以及其他注意事项 前言:工作时,在同时使用Hibernate的getSession().getHibernateTemplate()获取Session后进行数据查询时不是出现了"session is close"异常就是出现其他异常问题,痛定思痛,决定收集并整理相关资料,方便今后的使用. 一.session的获取 在hibernate中的Session对象通过SessionFactory来管理,可以通过使用openSession ().get

Hibernate中Session的get和load

hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别.测试版本:hibernate 4.2.0. get Session接口提供了4个重载的get方法,分别通过“持久类+主键”和“全类名+主键”以及“锁选项”来获取实体对象. public Object get(Class clazz, Serializable id); public Object get(Class clazz, Serializable id, L

hibernate中session

hibernate中的session是一级缓存,可以理解为进程级的缓存.在进程运行期间一直存在. session可以理解为一个可以操作数据库的对象 具体如何操作数据库? session中有方法, 如果只是单独的hibernate程序的话. 获得session之后,打开事务,操作数据库,提交(回滚事务),关闭session.就这样完成了操作DB ? Hibernate中session的使用: 在Hibernate中session主要是用来操作数据库? Hibernate在操作数据库前需要得到Ses

[转]Hibernate中Session的get和load

hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别.测试版本:hibernate 4.2.0. get Session接口提供了4个重载的get方法,分别通过“持久类+主键”和“全类名+主键”以及“锁选项”来获取实体对象. public Object get(Class clazz, Serializable id); public Object get(Class clazz, Serializable id, L

HttpSession与Hibernate中Session的区别

HttpSession与Hibernate中Session的区别 一.javax.servlet.http.HttpSession是一个抽象接口 它的产生:J2EE的Web程序在运行的时候,会给每一个新的访问者建立一个HttpSession,这个Session是用户身份的唯一表示.注意,是容器(Tomcat,Resin)自动创建的. 用途:存放这个用户的一些经常被用到的信息,例如:用户名,权限.例如在购物车程序里,存放用户买的商品. 销毁:一定时间(跟容器有关)内,用户无任何动作,session

Hibernate中Session的关闭处理(无法获取连接池)

java.lang.IllegalStateException: Pool not open 在使用Spring进行系统开发的时候,数据库连接一般都是配置在Spring的配置文件中,并且由Spring来管理的.在利用Spring + Hibernate进行开发时也是如此.下面是一个简单的Spring + Hibernate Dao的例子: 程序代码public class DaoReal extends HibernateDaoSupport implements Dao { public Li

Hibernate中Session之get和load方法的真正区别

最近在学习SHH框架中的hibernate,对Session的get和load方法,有点混不清楚,不知道区别在哪,或者对它们的区别感触不深.所以百度了一下,结果问题来了.百度的结果和实际测试的结果出入很大.主要是对get方法的说法跟实际运行的结果不一致. 先说一下观点吧: get不支持lazy,load支持lazy: 数据不存在时,get返回null,load则抛出ObjectNotFoundException异常. load方法可以返回实体的代理类实例,而get方法直接读取数据库,所以直接返回

转载!!!Hibernate中Session的缓存及对象的状态

对于session这个接口的学习可以说是最痛苦也是最复杂的,因为它所涉及的方面太多了,一些隐藏的机制也很多,谁让它是Central API呢. 对于它的几个最基本的方法如save().delete().flush()等的学习都花了我一定的时间.在深入了解这些这些方法前,了解session的缓存机制以及Hibernate中Java对象的状态对我们是很有帮助的. 一.Session的缓存 Java是纯面向对象的语言,因此不可能像C语言那样直接操纵内存,例如声明一段可用的内存空间.在Java里面,缓存