java报错Lock wait timeout exceeded; try restarting transaction

问题

博主问题是mysql表锁导致无法提交事务

临时处理

可以先kill卡住的线程

show processlist;

SELECT * FROM information_schema.INNODB_TRX;

在这里插入图片描述
这一列有值就执行。kill 值(pid)

场景

在这里插入图片描述

1.模拟事务提交

在这里插入图片描述

2.产生死锁
在这里插入图片描述
在这里插入图片描述

第二条sql一直在等待锁,无法执行

原理

在执行更新操作的时候,存在慢sql,未执行完成就提交新事务,导致代码报错,定位问题为

查询列没有索引,行锁升级到表锁

解决方案

给查询列增加普通索引

在这里插入图片描述

结果

不同行的更新事务可以正常执行
在这里插入图片描述

后续问题

对于mysql还有很多锁机制,在解决上述问题后,博主又遇到了插入锁住问题,查阅资料了解是间隙锁,通过修改事务隔离级别解决。

并发可能产生的问题罗列
脏读(Dirty read):

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。

丢失修改(Lost to modify):

指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

不可重复读(Unrepeatableread):

指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

幻读(Phantom read):

幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

事务隔离级别

mysql默认事务隔离级别是 Repeatable read;
在这里插入图片描述
查看当前事务级别

v5.7
SHOW VARIABLES LIKE 'tx_isolation';

博主是v8.0的数据库。
官方文档说v8.0之后就不用tx_isolation,用transaction_isolation替代了。

v8.0
SHOW VARIABLES LIKE 'transaction_isolation';

修改事务级别

//设置read uncommitted级别:
set session transaction isolation level read uncommitted;

//设置read committed级别:
set session transaction isolation level read committed;

//设置repeatable read级别:
set session transaction isolation level repeatable read;

//设置serializable级别:
set session transaction isolation level serializable;

参考文档
深入了解表锁和行锁
事务隔离

博主公众号
求关注
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值