2

这是否会导致 MySQL (InnoDB) 的竞争条件:

  1. 开始交易。

  2. 尝试获取记录。

  3. 如果记录不存在,则返回。

  4. 如果记录存在,请将其删除并添加一个日志条目,说明已删除。

  5. 结束事务(提交/回滚)。

是否可以在 2b 中的删除步骤之前启动另一个进程,检测记录的存在,然后让两个进程在日志中输入项目删除条目?

我需要采取什么预防措施吗?

谢谢。

4

4 回答 4

4

在步骤 2 中使用“选择更新”。只有一个进程能够获得该行的锁定,从而避免了您描述的情况。

于 2009-04-27T20:57:21.620 回答
1

我相信,熟练的程序员有正确的解决方案。既然您已经表明您使用的是损坏的 ORM 工具(一个不允许您查询更新的工具),我建议您将 INSERT 移动到日志表中,作为删除操作的触发器,这样您就可以避免重复入口。

于 2009-04-27T21:18:46.780 回答
1

开始交易。

删除记录 /* 使用与“尝试获取记录”相同的标准 */

如果响应表明记录确实被删除,则添加一个日志条目。

结束事务(提交/回滚)。

没有更多的比赛条件。

于 2010-08-19T15:52:51.427 回答
0

是的,在您阅读表格后,另一个事务可能会检查该表格。

更糟糕的是,由于事务的工作方式,即使在您删除该行之后,任何开始的新事务都会看到该行,因为您尚未提交删除。

SELECT ... FOR UPDATE是防止它的一种方法。

LOCK TABLE tablename是另一个。

不幸的是,由于您使用的是 ORM,所以我不能说它是否有能力执行其中任何一项。

于 2009-04-27T21:16:23.433 回答