Spring管理Bean、Hibernate事务,造成死锁问题的解决方法【探索篇】

一、先介绍一下手头的项目情况:

      1、同时操作4个表,分别是25w、55W(CRUD操作),以及另外另个副表也是25w、55w(只写)。

      2、应该也是50-100人左右同时操作。

 

二、这几天遇到的问题,就是数据死锁,以下附上错误部分错误提示:

      事务(进程 ID  62)与另一个进程已被死锁在  lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

      事务(进程 ID  63)与另一个进程已被死锁在  lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

      事务(进程 ID  64)与另一个进程已被死锁在  lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

      [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]事务(进程 ID  62)与另一个进程已被死锁在  lock 资源上,且该事务已被选作死锁牺牲品。请重新运行该事务。

 

三、这几天解决问题的过程中解决的各种思路以及各种经历(没有兴趣者可以略过,直接看后面的解决部分):

      1、怀疑Hibernate的findByProperty方法访问有问题。查找死锁的位置,发现只要是有以下获取list对象集的地方都会出错。

         

          

public List findByProperty(String propertyName, Object value) {
		log.debug("finding Persinfo instance with property: " + propertyName
				+ ", value: " + value);
		try {
			String queryString = "from Persinfo as model where model."
					+ propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

           而且以下我们的写法很常用:

          

List list = persinfoDAO.findByPerscode(perscode);
		if(!list.isEmpty()){
			Persinfo persinfo = (Persinfo)list.get(0);。。。

 

           所以如果要改写非常繁琐,但是怎么看都觉得没有问题,放弃,继续查找原因。

 

      2、怀疑是数据库连接太小,已经查到了出现死锁的位置。

           (此处略去N个字)

      3、怀疑Spring管理了所有的数据,改写配置文件: 

           (此处略去N个字)

      4、怀疑某一个用户锁住了表,另外的用户读取失败。(比较靠谱了) 

           (此处略去N个字)

      5、对Hibernate以及C3P0的设置进行优化。 

           (此处略去N个字)

      6、最后发现,是一个用户对表进行操作,操作之前事务会把表锁住,然后事务没有及时提交(解锁),就对表进行读取,造成了自己(的读取)对自己(提交写等操作的缓冲)进行等待,造成死锁。

 

四、解决方法:

      1、在业务层的一个方法里面:

          

Persinfo persinfo = (Persinfo)list.get(0);
                        ...
			persinfoDAO.update(persinfo);
                        ...
			if(...){
                                ...
				t402DAO.update(t402);
		        }
			if(...){
                                ...
				familyDAO.merge(family);
				if(...){
                                        ...
					t403DAO.update(t403);
				}
                                ...
				famifundDAO.update(famifund);
                                ...

				//硬性提交事务
				familyDAO.getHibernateTemplate().flush();
				t403DAO.getHibernateTemplate().flush();
				famifundDAO.getHibernateTemplate().flush();

           注意点:多个操作完成之后,一次性进行flush进行事务提交。

           其他思路:可以用AOP对业务层的某一个业务的所有方法进行定义,比如只读,或者整体事务,然后在Spring的配置文件进行配置。

 

五、附上我查阅资料之后发现的几个需要掌握的知识点:

      1、Spring集成Hibernate,C3P0的设置参数。

      2、事务隔离级别。

      3、Spring对于事务管理的几种方式。

      4、AOP的作用。

 

后记:

      因为时间仓促,加之自己的理解还不够透彻,稍后有空了,再整理一下,把Spring管理Bean、Hibernate事务的一些原理解剖清楚,再发表给大家。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值