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