Lock wait timeout exceeded; try restarting transaction

本文描述了在一个带有事务的service层方法中遇到的长时间执行与死锁问题,详细探讨了可能的原因及测试过程,并给出了暂时性的解决方案。

问题描述
这里写图片描述
在带有事物的service层中authAssignPkg()方法用于处理多个操作,其中一个操作就是this.dao.batchSave(),batchSave()方法中又重新开启与提交事物。当在Action层中直接调用authAssignPkg()方法,通过控制台打印的信息会发现,authAssignPkg()方法中this.dao.batchSave()执行的时间特别长,最后控制台打印错误的信息为:Lock wait timeout exceeded; try start transaction。

相关代码
这里写图片描述

这里写图片描述

分析报错原因
开始我猜测为事物嵌套造成的,即开启事物A,并在事物A中开启事物B,在B事物提交的时候就会发现,时间超时数据库被锁

验证猜测

package com.transaction.demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class TransDemo {

    private SessionFactory sf;

    @Before
    public void beforeClass(){
        System.out.println("come befote");
        XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("src/main/resources/applicationContext.xml"));
        PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
        cfg.setLocation(new FileSystemResource("src/main/resources/config.properties"));
        cfg.postProcessBeanFactory(factory);
        sf=(SessionFactory)factory.getBean("sessionFactory");

    }


    @Test
    public void test(){
        System.out.println("sf:"+sf);
        Session session = sf.openSession();
        try {
            session.beginTransaction();
            Book book=new Book();
            book.setId(1L);
            book.setResType("book");
            book.setName("aaa");
            session.update(book);
            otherTrans();
            session.getTransaction().commit();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            session.getTransaction().rollback();
            throw new RuntimeException(e);
        }finally{
            session.close();
        }
    }

   public void otherTrans(){
       Session session = sf.openSession();
        try {
            session.beginTransaction();
            Book book=new Book();
            book.setId(2L);
            book.setResType("book");
            book.setName("bbb");
            session.update(book);
            session.getTransaction().commit();
        } catch (Exception e) {
            // TODO: handle exception
            session.getTransaction().rollback();
            throw new RuntimeException(e);
        }finally{
            session.close();
        }
   }

}

通过测试发现test()方法可以正常运行,所以猜错失败。

结论
最终也不是很清楚是什么原因造成的死锁,只得把批量保存的方法提到Action层。此处留一个坑,后期继续解决

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值