经业务侧反馈,系统MySQL数据库锁等待比较严重,查看MySQL数据库锁等待情况如下:
可知,锁等待主要在`**** `.`**** `这个表上。
可知,表有一个自增主键playlistid和唯一索引createuserid。由innodb auto_increment的锁定模式设置为1,可知此模式下所有insert...select类语句针对自增主键会使用auto_inc表级锁,并保持到语句结束。同一时刻只有一个语句可以持有auto_inc锁。 由innodb状态信息得知,同时有多个事务并发对****这张表进行insert操作。事务1的insert操作会触发unique key的冲突检查进行一个当前读并加上X锁,等待持有自增主键的auto_inc锁。事务2的insert操作首先获得自增主键的auto_inc锁,此时为表级锁,等待持有对应记录的X锁(包含Gap锁)。此时事务1和事务2造成死锁,因为事务1的权重较小,MySQL选择回滚事务1。
建议修改业务逻辑,将insert...select语句修改为insert ingore或者replace的方式。
将多个事务的执行顺序进行调整避免锁等待。
业务程序中一定要做好事务控制,事务结束时务必确保显示提交,释放持有的锁避免阻塞。程序中应尽量保证事务的原子性,一个事务实现一个逻辑,避免多个逻辑混合在一个事务中。