这是否会导致 MySQL (InnoDB) 的竞争条件:
开始交易。
尝试获取记录。
如果记录不存在,则返回。
如果记录存在,请将其删除并添加一个日志条目,说明已删除。
结束事务(提交/回滚)。
是否可以在 2b 中的删除步骤之前启动另一个进程,检测记录的存在,然后让两个进程在日志中输入项目删除条目?
我需要采取什么预防措施吗?
谢谢。
这是否会导致 MySQL (InnoDB) 的竞争条件:
开始交易。
尝试获取记录。
如果记录不存在,则返回。
如果记录存在,请将其删除并添加一个日志条目,说明已删除。
结束事务(提交/回滚)。
是否可以在 2b 中的删除步骤之前启动另一个进程,检测记录的存在,然后让两个进程在日志中输入项目删除条目?
我需要采取什么预防措施吗?
谢谢。
在步骤 2 中使用“选择更新”。只有一个进程能够获得该行的锁定,从而避免了您描述的情况。
我相信,熟练的程序员有正确的解决方案。既然您已经表明您使用的是损坏的 ORM 工具(一个不允许您查询更新的工具),我建议您将 INSERT 移动到日志表中,作为删除操作的触发器,这样您就可以避免重复入口。
开始交易。
删除记录 /* 使用与“尝试获取记录”相同的标准 */
如果响应表明记录确实被删除,则添加一个日志条目。
结束事务(提交/回滚)。
没有更多的比赛条件。
是的,在您阅读表格后,另一个事务可能会检查该表格。
更糟糕的是,由于事务的工作方式,即使在您删除该行之后,任何开始的新事务都会看到该行,因为您尚未提交删除。
SELECT ... FOR UPDATE
是防止它的一种方法。
LOCK TABLE tablename
是另一个。
不幸的是,由于您使用的是 ORM,所以我不能说它是否有能力执行其中任何一项。