mysql怎么让表不死锁 mysql锁定表( 三 )


调查后发现,当当前索引是一个 普通索引 的时候,会加一个gap lock来防止幻读,此gap lock 会锁住一个左开右闭的区间 。假设索引为xx_idx(xx_id),数据分布为1,4,6,8,12,当更新xx_id=9的时候,这个时候gap lock的锁定记录区间就是(8,12],也就是锁住了xxid in (9,10,11,12)的数据,当有其他事务要插入xxid in (9,10,11,12)的数据时,就会处于等待获取锁的状态 。
ps:当前索引不是普通索引,而且是唯一索引等其他情况,请参考下面资料
MySQL 加锁处理分析
回到我自己的案例中,重新屡一下事务1的执行过程:
因为普通索引
KEY hotel_date_idx ( hotel_id , rate_date )
的关系 这段sql会获取一个gap lock,范围(2,11111]
这段sql会获取一个insert intention lock (waiting)
再看事务2的执行过程
因为普通索引
KEY hotel_date_idx ( hotel_id , rate_date )
的关系 这段sql也会获取一个gap lock , 范围也是(2,11111](根据前面的知识,gap lock之间会互相兼容,可以一起持有锁的)
这段sql也会获取一个insert intention lock (waiting)
看到这里 , 基本也就破案了 。因为普通索引的关系,事务1和事务2的gap lock的覆盖范围太广,导致其他事务无法插入数据 。
重新梳理一下:
所以从结果来看,一堆事务被回滚,只有10007数据被更新成功
gap lock 导致了并发处理的死锁
在mysql默认的事务隔离级别(repeatable read)下 , 无法避免这种情况 。只能把并发处理改成同步处理 。或者从业务层面做处理 。
共享锁、排他锁、意向共享、意向排他
record lock、gap lock、next key lock、insert intention lock
show engine innodb status
如何避免mysql死锁问题处理方式:
1. 在表上建立一个聚集索引 。
2. 对语句更新mysql怎么让表不死锁的相关字段建立包含索引 。
如何预防死锁
1.尽量避免并发mysql怎么让表不死锁的执行涉及到修改数据mysql怎么让表不死锁的语句 。
2.编写应用程序,让进程持有锁的时间尽可能短,这样其它进程就不必花太长的时间等待锁被释放 。
关于mysql怎么让表不死锁和mysql锁定表的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。

推荐阅读