首页
注册
登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请
登录
V2EX
›
shidakang0
›
全部回复第 1 页 / 共 1 页
回复总数
2
329 天前
回复了
cnoder
创建的主题
›
MySQL
›
这为什么会死锁呢,为什么换 duplicate key update 就不报错了,有沒有 dba 大哥说说
死锁通常在多个事务同时尝试以不兼容的方式锁定资源时发生。在您提供的信息中,两个事务都尝试对同一资源进行替换操作,这涉及到删除旧记录和插入新记录的过程。由于 REPLACE INTO 实质上是一个删除后跟着一个插入的操作组合,两个事务都试图获取同样的锁,从而导致死锁。
在 REPEATABLE-READ 隔离级别下,InnoDB 存储引擎为表中的索引记录保持行锁,直到事务结束。这意味着一旦事务获得了某个记录的锁,它将在事务结束前保持该锁定状态。如果另一个事务尝试执行与已锁定的记录相关的操作,则该事务将进入等待状态,直到第一个事务完成。如果两个事务互相等待对方释放锁,就会发生死锁。
在您的案例中,两个事务都在尝试执行 REPLACE INTO 操作,并且因为涉及到删除操作,它们都需要 X (排他锁)。第一个事务等待释放因为第二个事务持有的旧记录的锁,而第二个事务等待释放第一个事务尝试插入的新记录相同位置的锁。这就是为什么发生死锁的原因。
当改用 INSERT ... ON DUPLICATE KEY UPDATE 时,如果尝试插入的记录的唯一键已经存在,则不会删除旧记录,而是更新它。这意味着只需要一次索引记录的锁,减少了锁的复杂性和冲突的可能性,因此不再出现死锁错误。
为了避免死锁,可以考虑以下策略:
重新考虑索引策略,确保索引尽可能高效,这样可以降低锁定的需求。
尽可能减少事务大小,执行更多的小事务而不是少数几个大事务。
对于可能会导致死锁的操作,可以使用排他锁( SELECT ... FOR UPDATE ),或者在应用逻辑中实现重试机制。
确保应用程序中的事务按照相同的顺序访问数据库对象,以减少锁冲突的可能性。
355 天前
回复了
GoTop
创建的主题
›
Telegram
›
google voice 现在无法使用解码平台注册了,没有 gv 手机号怎么注册 TG?
我这可以帮忙注册需要的话可以联系我
关于
·
帮助文档
·
博客
·
API
·
FAQ
·
实用小工具
·
2790 人在线
最高记录 6679
·
Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 11ms ·
UTC 15:23
·
PVG 23:23
·
LAX 07:23
·
JFK 10:23
Developed with
CodeLauncher
♥ Do have faith in what you're doing.