hibernate之openSession 和 getCurrentSession 概述

1.getCurrentSession与openSession的概述


1.openSession创建session时autoCloseSessionEnabled参数为false,即在事物结束后不会自动关闭session,需要手动关闭,如果不关闭将导致session关联的数据库连接无法释放,最后资源耗尽而使程序当掉。               

2.getCurrentSession创建session时autoCloseSessionEnabled,flushBeforeCompletionEnabled都为true,即事务提交后自动关闭session,并且session会同sessionFactory组成一个map(以sessionFactory为主键,注意一个应用中可以有多个sessionFactory)绑定到当前线程(ThreadLocal方式,以threadLocal实例作为key)。

3.getCurrentSession()与openSession()关联

 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在 getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 

(1)在单独使用hibernate而没有集成spring时,需要指定CurrentSessionContext 的实现类:thread或jta。

 * 如果采用jdbc独立引用程序配置如下:
    <propertyname="hibernate.current_session_context_class">thread</property>
  * 如果采用了JTA事务配置如下  
   <property name="hibernate.current_session_context_class">jta</property>

thread和jta对应的CurrentSessionContext实现类在 currentSession() 执行时,如果当前 Session 为空,currentSession 会调用SessionFactory  openSession 创建一个新的session并且绑定到当前线程

(2)在集成spring时,内部会默认使用spring提供的CurrentSessionContext 实现类:SpingSessionContext,此时再配置hibernate.current_session_context_class属性指定CurrentSessionContext 实现类就无效,甚至会报异常。SpringSessionContext在currentSession()执行时,如果当前SpingSessionContext中session为空,则直接抛出异常“No Session found for current thread ”。那么集成spring时要怎么才能避免session不为空呢?方法:通过配置事务管理,让事务管理器自动打开session和事务,并绑定到SpingSessionContext中。也就是说某个方法要用到session且是通过getCurrentSession()方法获取时,要让该方法受事务的管理,如用@Transactional注解,或用<tx 标签设置事务管理范围。


 

2.getCurrentSession()原理

利于ThreadLocal模式管理Session。

3.ThreadLocal详解

         关键:

         1. Thread类内部有一个属性threadLocals,该属性的类型是ThreadLocal.ThreadLocalMap。即Thread类内部有一个属性,该属性是ThreadLocal类的内部类ThreadLocalMap,该内部类是一个map

         2.ThreadLocal.get()方法内部操作:获取当前线程的threadLocals,以当前ThreadLocal实例作为keythreadLocals中获取value

       3.ThreadLocal.set(t)方法内部操作:获取当前线程的threadLocals,以当前ThreadLocal实例作为keyt放入threadLocals

         4.ThreadLocal变量的作用是:通过set(t)方法将t放入当前线程的threadLocals(是一个map)变量中,以当前ThreadLocal实例为key。通过get()方法从当前线程的threadLocals变量中以当前ThreadLocal实例为key取出数据t。这样就是实现了:每个线程都有自己的变量t,而不会冲突。即ThreadLocal变量其实是一个工具,该工具用以把数据存储在当前线程中以及从当前线程中取出数据,而存数和取数都是以ThreadLocal实例为标志的。

         5.ThreadLocal变量一般都是用staticfinal修饰,因为:类A中声明了ThreadLocal变量:

         原因(1.一个线程先先后多次通过AThreadLocal变量存取数据,如果ThreadLocal变量是static的,即该实例前后不变同时同一个实例,所以可以准确定位到线程中之前存储的数据。相反,若是ThreadLocal变量不是static的,则每次调用类AThreadLocal变量时,该ThreadLocal变量都是新建的实例,这样就导致前后ThreadLocal变量实例不一致了,就无法找到以前依据ThreadLocal变量实例存储的数据,即依据新的ThreadLocal实例从当前线程中取出来的数据是null

         原因(2.不同的线程通过AThreadLocal变量存取数据都是用同一个ThreadLocal变量实例,ThreadLocal变量是static的。

 

         6.不同类中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值