MySQL语句:
INSERT ... ON DUPLICATE KEY UPDATE ...
看起来像一个应该是线程安全的单个语句(从某种意义上说,在其执行期间不会发生对同一数据的并发查询)。但另一方面,它可以在内部分解为insertandupdate语句,我想知道它是否仍然保证线程安全?
我的意思是,例如,delete在insert和update来自并发线程之间是否可能存在会导致update失败的情况?
我认为insert on duplicate key update应该是线程安全的,但文档似乎没有以明文形式说明。有人可以提供有关该主题的证明链接吗?内部是如何实施的?
RDBMS 使用锁和隔离级别来控制并行运行的会话如何访问相同的数据。不存在线程安全这样的东西,也不存在会话安全这样的东西。只有并发控制。
如果使用myisam表类型,那么所有数据修改语句都会锁定整个表(myisam在有限情况下可以进行并发插入,但删除确实需要始终加表锁)。因此,删除不会干扰insert ... on duplicate key update....
如果您使用innodb表类型,那么情况会稍微复杂一些,因为它应用了行级锁。正如 mysql 手册中关于各种 sql 语句设置的锁所述:
INSERT ... ON DUPLICATE KEY UPDATE 与简单 INSERT 的不同之处在于,当发生重复键错误时,将在要更新的行上放置独占锁而不是共享锁。对重复的主键值采用独占索引记录锁定。对重复的唯一键值采取独占的下一键锁定。
因此,首先 mysql 锁定插入的新记录。如果出现重复键错误,则只有此时重复记录才会被锁定。从技术上讲,在重复键错误和在重复记录上放置排他锁之间,删除语句可能会删除重复记录。但是,这不会使更新语句失败。它根本不会更新任何记录。
但这需要删除语句的时间非常准确。
仅当删除语句insert ... on duplicate key update...在重复键错误后获取重复记录上的排他锁并保持该锁的时间长到插入事务超时时,该语句才可能失败。
| 归档时间: |
|
| 查看次数: |
6083 次 |
| 最近记录: |