Lock wait timeout exceeded; try restarting transaction(死锁问题)

在线上发现了死锁问题,排查解决之后,根据其原因写了一个demo,记录一下。

一:DEMO代码

    /**
     * 数据插入
     */
    @RequestMapping("/test3")
    @Transactional
    public void test3() {
        UEmployee uEmployee = new UEmployee();
        uEmployee.setId("1111111111111111");
        uEmployee.setName("test1");
        uEmployee.setPsd("123456");
        uEmployeeService.getuEmployeeDAO().insert(uEmployee);
        System.out.println("uEmployee" + uEmployee.getId());
        while (true) {
        }
    }

    /**
     * 数据删除
     */
    @RequestMapping("/test4")
    @Transactional
    public void test4() {
        UEmployee uEmployee = new UEmployee();
        uEmployee.setId("1111111111111111");
        uEmployee.setName("test1");
        uEmployee.setPsd("123456");
        uEmployeeService.getuEmployeeDAO().deleteByPrimaryKey(uEmployee.getId());
        System.out.println(uEmployee);
    }

二:使用postMan访问

先访问test3,将数据插入数据库

Lock wait timeout exceeded; try restarting transaction(死锁问题)

Lock wait timeout exceeded; try restarting transaction(死锁问题)

状态会一直是访问中,死循环,无法执行完成,没有数据返回到客户端

再访问test4

Lock wait timeout exceeded; try restarting transaction(死锁问题)

一开始无反应,等待中,一段时间后,报错。提示死锁;

三:原理分析及排查解决方法

首先,test4报错,提示死锁,说明当前操作数据有其他线程在执行操作。查找其他可能操作当前数据代码,找到可能代码之后,尝试重现异常。重现完成,解决代码问题,删除死锁(下面有删除数据库死锁方法),测试完成,上线。

这里出现问题的原因是,操作的是一条数据,而且test3在数据库中插入之后,因为逻辑死循环的问题,没有执行完当前方法,也就没有走完@Transactional 所注解的方法体,所以没有提交事务(commit),其他线程访问操作未提交的数据,也就理所当然的会出现死锁问题.

a.在数据库删除死锁方法

在数据库中找到"information_schema"表,选中.执行sql "SELECT * FROM INNODB_TRX;"会查询出没有执行完成的sql,

Lock wait timeout exceeded; try restarting transaction(死锁问题)

kill掉当前sql线程:(trx_mysql_tread_id)

Lock wait timeout exceeded; try restarting transaction(死锁问题)

再次查询:

Lock wait timeout exceeded; try restarting transaction(死锁问题)

kill成功

 

上一篇:UnicodeDecodeError gbk codec can't decode byte in position illegal multibyte sequence


下一篇:python中字符串的常用拼接