我需要(我将永远需要)锁定共享模式吗?FOR UPDATE 在事务中?

5 php mysql innodb transactions foreign-keys

我正在痛苦地试图理解如何最好地编写我的代码和查询

直接问一个问题:我是否需要或将需要明确写入LOCK IN SHARED MODEFOR UPDATE在事务中(除了READ UNCOMMITTED那些)?

如果我有外部键,是否需要明确选择行以将锁定应用于这些行,还是外键定义就足够了?

Meh*_*ran 4

简短的回答:绝对是的。

完整的答案:这取决于用例。也许在大多数情况下,InnoDb 使用的默认锁就足够了。这些锁可确保您的数据在事务内保持一致。但这里有一个需要使用锁的场景SELECT ... FOR UPDATE

假设您正在制作一个 Web 应用程序,其中会话数据存储在数据库中。当涉及到会话数据时,竞争条件是一个问题。虽然当使用文件存储会话数据时可以满足此问题,但如果将它们移动到数据库,则您有责任确保请求不会覆盖彼此的会话更改。在这种情况下,您需要使用 MySQL 读取会话数据,FOR UPDATE以确保其他请求将等待此请求写回会话并提交事务,然后才能读取它。

[更新]

这是共享模式的一个用例:

当您想要确保某些记录在事务结束时保持不变时,共享模式非常有用。例如,当您尝试将带有外键的子记录插入父记录时,并且父记录已插入到先前的事务中。在这种情况下,您将首先选择锁定在共享模式下的父记录,然后尝试插入子记录,以确保插入子记录时,父记录仍然存在。这样其他会话仍然可以读取父记录,但没有人可以更改它。这只是我的首要考虑,但在共享模式锁的所有用例中,这个事实仍然是一样的,即您希望记录保持不变,同时其他人仍然可以读取它。

[更新]

关于事务隔离级别SERIALIZABLEMySQL的文档说得非常清楚。如果您以这种方式设置事务级别,那么SET autocommit = 0;它与最后REPEATABLE READ编写所有选择查询的级别完全相同(除非您明确提及)。这意味着您将(显式或隐式)触摸的所有内容都将被锁定。那些没有提到锁或有锁的选择将被锁定在共享模式下,其余的将被锁定在独占模式下。LOCK IN SHARE MODEFOR UPDATELOCK IN SHARED MODE