INSERT ... ON DUPLICATE KEY UPDATE ...
insert
和
update
语句,我想知道它是否仍然保证线程安全?我的意思是,例如,在
delete
和
insert
之间是否可能有一个
update
来自并发线程,导致
update
失败?我认为
insert on duplicate key update
应该是线程安全的,但文档似乎没有以明文形式说明。有人可以提供有关该主题的证明链接吗?内部是如何实现的?
如果使用MyISAM表类型,那么所有数据修改语句
都会锁定整个表(MyISAM可以在有限的情况下进行并发插入,但删除确实需要始终锁定表)。因此,删除不会干扰 insert ... on duplicate key update...
。如果使用InnoDB表类型,那么情况会稍微复杂一些,因为它应用了行级锁。正如MySQL手册上所说的
各种SQL语句设置的锁:
INSERT ... ON DUPLICATE KEY UPDATE 与简单 INSERT 的不同之处在于,当发生重复键错误时,将在要更新的行上放置独占锁而不是共享锁。对重复的主键值采用独占索引记录锁定。对重复的唯一键值采取独占的下一键锁定。因此,首先MySQL会锁定插入的新记录。如果出现重复键错误,只有此时重复记录才会被锁定。从技术上讲,在重复键错误和在重复记录上放置排他锁之间,删除语句可能会删除重复记录。但是,这不会使更新语句失败。它根本不会更新任何记录。
但这需要非常准确的删除语句时间。
仅当删除语句在重复键错误后获取重复记录上的排他锁并持有该锁的时间长到插入事务超时时,
insert ... on duplicate key update...
语句才可能失败。