MySql数据库死锁deadlock

时间:2021-05-30 08:31:38

 

今天在项目性能测试中遇到个Mysql的DeadLock的问题。

后来根据数据库日子查找原因,大概模拟一下发生的情形。

 

数据库用的innoDB。

InnoDB行锁是通过给索引上的索引项加锁来实现的,InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!

下面例子中id是主键,操作都走索引,锁都是row lock。

  table中数据 MySql数据库死锁deadlock  

 

用2个线程做如下操作,将发生死锁现象,且1个线程执行成功,另一个线程失败。

MySql数据库死锁deadlock

 

最终结果:第一条数据被改变,第3条数据不变。

MySql数据库死锁deadlock

 

MySql的InnoDB,\加了事务的select语句索引的记录,会加S锁, insert,delete,update会加X锁。

设定左边为线程1,右边为线程2

线程1在id=1的一行记录上加了S锁, 当线程2要update操作这行记录时,要在记录上加X锁, 此时需要等待线程1释放id=1记录上的S锁。

线程2在id=3的一行记录上加了S锁, 当线程1要update操作这行记录时,要在记录上加X锁, 此时需要等待线程2释放id=3记录上的S锁。

彼此互相等待,然后就死锁了。

Mysql释放死锁的机制,看锁定的记录数,一般会允许锁定记录多的事务执行通过, 而锁定记录少的事物回滚。范围同等时应该是按X锁请求的先后了。

 

补充说明: InnoDB 如果where后面的条件字段没有索引,则加锁时是会锁表。走索引只会锁查询或操作的记录。InnoDB事务中的查询条件需要小心了

互斥

S

X

S

X

 

先写这么多。