问题排查记录:数据库隔离级别引起的死锁

问题原因: 数据库迁移,新库的数据库事务隔离级别升了一个等级,由 读已提交(read-committed) 升到了 可重复读(repeatable-read)
导致了 insert into select 语句,会把自己锁住( 因为select和insert是同一个表,repeatable-read 模式下 select也会加锁)

解决方案1:把数据库级别改回 read-committed
解决方案2:在锁住的表加索引。因为不走索引的话,会把行级锁升级成表级锁。参考链接: https://blog.csdn.net/asdfsadfasdfsa/article/details/83030011

顺便说一下事务的隔离级别:
查看当前数据库的隔离级别: select @@tx_isolation
修改当前会话的隔离级别: SET session TRANSACTION ISOLATION LEVEL Serializable;(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)
修改全局事务隔离级别: SET global TRANSACTION ISOLATION LEVEL Serializable;(参数可以为:Read uncommitted|Read committed|Repeatable read|Serializable)

mysql 4种隔离级别从低到高:

  • Read Uncommitted(读取未提交内容)
    问题:脏读
  • Read Committed(读取提交内容)
    问题:不可重复读-同一个事务中执行完全相同的select语句时可能看到不一样的结果
  • Repeatable Read(可重读)(mysql默认隔离级别)
    问题:幻读-读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。 InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题
  • Serializable(可串行化)

你可能感兴趣的:(问题排查记录:数据库隔离级别引起的死锁)