作者回复: 这个回答是我想要的。
Innodb提供了wait-for graph算法来主动进行死锁检测,我们可以通过innodb_deadlock_detect = on 打开死锁检测。
作者回复: 在3的insert操作中,回去获取插入意向锁,而插入意向锁也是一种gap锁,根据矩阵图,插入意向锁和gap间隙锁是冲突的,所以insert操作需要等待间隙锁的释放。
作者回复: for update是一种悲观锁实现,我们可以使用性能更好的乐观锁来实现,通过版本号来实现数据更新不丢失问题,这种方式是最佳选择。
而对于插入时防重复问题,可以对不允许重复字段设置唯一索引,进行唯一约束,这是一种不友好的实现方式。
作者回复: 由于 order_no 列为非唯一索引,此时又是 RR 事务隔离级别,所以事务A的select获取的是gap锁,事务B也是获取的gap锁,gap锁是相互兼容的,所以可以同时获取到。
是为了防止幻读,需要通过插入意向锁实现阻塞等待gap锁的释放。
作者回复: 在更新status时,由于是根据条件order_no来更新状态的,所以获取的是index_order_status索引,index_order_status是一个联合索引,由于不是主键,所以是非聚簇索引。
作者回复: 因为主键是唯一索引,所以不会使用next-key lock
作者回复: select col from t where t.col = 'xx' for update不会导致索引失效的,使用排他锁是不是发生了死锁了呢?
作者回复: 互相锁等待,又无法释放彼此等待的锁,就是死锁状态了
作者回复: 是的
作者回复: 一样是不兼容的
作者回复: 索引和数据是两个概念,我们说过,聚合索引的叶子节点会存放整个数据,而辅助索引的叶子节点存放的是主键id
作者回复: 由于RC隔离级别只解决了脏读,所以是记录锁
作者回复: 如果我们之前使用辅助索引来更新数据库,就需要修改为使用聚簇索引来更新数据库。
作者回复: 过来人👍🏻