getCurrentSession and openSession

本文介绍了如何在Spring框架中配置Hibernate的LocalSessionFactoryBean,并探讨了getCurrentSession()与openSession()的区别,以及如何通过ThreadLocal管理Session。
部署运行你感兴趣的模型镜像

在spring配置文件中,只需要配置在sessionFactory配置

 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 

LocalSessionFactoryBean实现了org.springframework.beans.factory.FactoryBean接口, 

spring在装配的时候, 如果发现实现了org.springframework.beans.factory.FactoryBean接口, 

就会使用FactoryBean#getObject() 方法返回的对象装配,具体的可以看下文档. 

如果你想拿到LocalSessionFactoryBean实例, 在id前面加个'&'就可以了,在你的配置文件中BeanFactory.getBean('&sessionFactory')拿

的就是LocalSessionFactoryBean的实例. 

所以通过spring框架,LocalSessionFactoryBean可以生成factoryBean,可以通过factoryBean.getCurrentSession获取session。并不需要在hibernate中配置

<property name="hibernate.current_session_context_class">thread</property>或者

<property name="hibernate.current_session_context_class">jta</property>



1、getCurrentSession()与openSession()的区别?

* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession()
创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession()
创建的session必须手动关闭
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
<property name="hibernate.current_session_context_class">thread</property>
* 如果使用的是全局事务(jta事务)

<property name="hibernate.current_session_context_class">jta</property>

利于ThreadLocal模式管理Session
   早在Java1.2推出之时,Java平台中就引入了一个新的支持:java.lang.ThreadLocal,给我们在编写多线程程序
   时提供了一种新的选择。ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,
   而是thread local variable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)
   其实的功用非常简单,就是为每一个使用某变量的线程都提供一个该变量值的副本,是每一个线程都可以独立地改变自己的副本,
   而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有一个该变量。 
   ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,
   用于存储每一个线程的变量的副本。比如下面的示例实现(为了简单,没有考虑集合的泛型): 
public class HibernateUtil {

public static final ThreadLocal session =new ThreadLocal();

public static final SessionFactory sessionFactory;
   static {
      try {
        sessionFactory = new Configuration().configure().buildSessionFactory();
      } catch (Throwable ex) {
           throw new ExceptionInInitializerError(ex);
      }     
}

     public static Session currentSession() throws HibernateException {
        Session s = session.get();
        if(s == null) {
          s = sessionFactory.openSession();
          session.set(s);
           }
         return s;
       }

    public static void closeSession() throws HibernateException {
           Session s = session.get();
        if(s != null) {
            s.close();
        }
        session.set(null);
    }
}



 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory  openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

{ // 创建固定大小线程池 logger.info("死锁测试"); ExecutorService executor = Executors.newFixedThreadPool(2); // 线程1 executor.submit(() -> { Session cnSeqnumSession=sessionFactory.openSession(); cnSeqnumSession.getTransaction().begin(); DaoTemplate cnseqDaoTemplate = new DaoTemplateImpl() ; cnseqDaoTemplate.setExternalSession(cnSeqnumSession); cnseqDaoTemplate.executeSql("update cn_seqnum b set b.seq_currentval='376385' where seq_id='glno' "); cnSeqnumSession.getTransaction().commit(); Session session = sessionFactory.openSession(); session.getTransaction().begin(); DaoTemplate daoTemplateImpl = new DaoTemplateImpl(); daoTemplateImpl.setExternalSession(session); daoTemplateImpl.executeSql("update biz_fair_value set workdate='20250306' where id='99999'"); daoTemplateImpl.executeSql("update dc_log set tx_tx_date = '20250306' where TRACE_NO = 'GL202502280000018624' and trace_cnt='1'"); session.getTransaction().commit(); cnSeqnumSession.close(); session.close(); }); // 线程2 executor.submit(() -> { Session cnSeqnumSession=sessionFactory.openSession(); cnSeqnumSession.getTransaction().begin(); DaoTemplate cnseqDaoTemplate = new DaoTemplateImpl() ; cnseqDaoTemplate.setExternalSession(cnSeqnumSession); cnseqDaoTemplate.executeSql("update cn_seqnum b set b.seq_currentval='376386' where seq_id='glno' "); cnSeqnumSession.getTransaction().commit(); Session session = sessionFactory.openSession(); session.getTransaction().begin(); DaoTemplate daoTemplateImpl = new DaoTemplateImpl(); daoTemplateImpl.setExternalSession(session); daoTemplateImpl.executeSql("update biz_fair_value set workdate='20250306' where id='99
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值