线上收到了一个报警,主要内容如下:
异常:Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:,
原因:最终锁定是和一个插入或者更新的语句有关,INSERT ... ON DUPLICATE KEY UPDATE
结果:这个语句可能导致death lock死锁也有可能导致主从模式下的replication数据不一致问题
mysql 官网对于死锁有这样的解释:
一般死锁场景是发生在不同的事务中,获取自己所需的资源又获取不到导致僵持
INSERT ... ON DUPLICATE KEY UPDATE 如何产生死锁呢?执行此语句时,innodb引擎会先判断插入的行是否产生重复key错误,如果存在,在对该现有的行加上S(共享锁)锁,返回该行数据给mysql,然后mysql执行完duplicate后的update操作,然后对该记录加上X(排他锁),最后进行update写入。
死锁原因:比如有两个不同的事务操作的INSERT ... ON DUPLICATE KEY UPDATE 语句一模一样,事务1 执行语句发现有重复key则获取此记录的S(读)锁,获取该记录,还未修改时事务2 执行同样的语句,也发现有此记录则获取S锁,此时事务1 继续执行进行修改获取X(写)锁,要等待事务2 释放读锁, 此时事务2 也要执行修改也要获取X 锁,等待事务1 释放S 锁,此时两者就会进入僵持最终造成死锁。
主从不一致原因:同样是两个不同的事务,执行不同的语句,但是判断的记录存在的依据是一致的,如图
感谢观看~
祝好~