问题
博主问题是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;
博主公众号
求关注