Hibernate不同的session实例引发的线程阻塞和MySQL进程阻塞

Hibernate中获取两种Session实例的方法

在hibernate中有两种方法获得session

1.openSession()
2.getCurrentSession()

两种方法的区别
1.openSession()每次创建新的session对象,getCurrentSession()使用现有的session对象 (类似单例模式)
2.getCurrentSession在事务提交或者回滚之后会自动关闭,而openSession()需要手动关闭(session.close()),如果使用openSession()后未关闭,多次创建后会导致线程池溢出。

如果使用的getCurrentSession()方法 就要在hibernate.cfg.xml文件中进行配置,Hibernate4.0以后可以采用spring配置文件
加@Trancation注解的形式获取当前的session实例,例

<!--  5.事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!--6.事务-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

由于在项目中引用了Java Socket,所以开启多线程去解析socket客户端的数据,突然发现一个坑爹的问题,当同时开启20个线程去解析数据的时候,会发生整个服务的线程阻塞和MySQL进程sleep

定位线程阻塞问题

show processlist发现如图所示,
在这里插入图片描述
许多mysql进程sleep,我kill掉所有正在运行的进程,然后
set global wait_timeout=300;
set global interactive_timeout=300;
重启服务以后,当线程开启到50个的时候发现又有大量的进程sleep
我开始定位程序中的问题,我查询用的是getCurrentSession,但解析客户端socket数据用的openSession

   /**
   	 *getCurrentSession
	 * 获取新的session
	 * @return
	 */
	public Session findSession() {
		return sessionFactory.getCurrentSession();
	}
	
	/**
	  *openSession
	  *
	  */
	//创建会话工厂
	SessionFactory sessionFactory=(SessionFactory) 
	SpringContext.getBean("sessionFactory");
	//创建会话session
	Session session=sessionFactory.openSession();
	//开启会话事务
	Transaction transaction=session.beginTransaction();

之前使用getCurrentSession的时候都是使用@trancation注解自动提交事务和关闭session,但opneSession需要手动关闭,
这里由于没有手动关闭,造成A事务和B事务同时对Table表操作,导致数据库死锁,当我在每次执行完数据解析以后加上
session.flush();
session.close();
重启服务跑一下,再没遇到线程阻塞的情况(想拍死自己),但访问主线程查询的时候发现又遇到问题,如图
在这里插入图片描述
我在配置文件中加了

> <prop key="hibernate.current_session_context_class">thread</prop>

Spring和Hibernate整合事务配置之current_session_context_class

hibernate.current_session_context_class设置原来配置事务模式:

<prop key="hibernate.current_session_context_class">thread</prop>

会出现不存在激活的事务现象,主要原因是由于咋Spring管理事务中currentsession是绑定下springsessioncontext中的,而不是绑定在threadlocalsessioncontext中的。
hibernate.current_session_context_class常用3种配置:
jta,thread,org.springframework.orm.hibernate4.SpringSessionContext

hibernate.current_session_context_class=thread

实质是: hibernate.current_session_context_class=
org.hibernate.context.internal.ThreadLocalSessionContext
org.hibernate.context.internal.ThreadLocalSessionContext -
当前session通过当前执行的线程来跟踪和界定。

hibernate.current_session_context_class=jta

实质是: hibernate.current_session_context_class=
org.hibernate.context.internal.JTASessionContext
org.hibernate.context.internal.JTASessionContext-
当前session根据JTA来跟踪和界定。这和以前的仅支持JTA的方法是完全一样的。

hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

实质是 Spring @Transactional声明式事务管理,”currentSession”的定义为: 当前被 Spring事务管理器
管理的Session,此时应配置:
hibernate.current_session_context_class=org.springframework.orm.hibernate4.SpringSessionContext

spring 整合hibernate管理事务后,由Spring的TransactionManager管理事务后, currentSession是绑定到SpringSessionContext的,而不是thread。
此时hibernate.current_session_context_class应该是SpringSessionContext,而它又会在使用LocalSessionFactoryBean时自动的设置。
所以就不需要你去设置current_session_context_class

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值