我是否需要(我将需要)锁定共享模式|在交易中进行更新?

时间:2014-07-01 09:03:18

标签: php mysql transactions foreign-keys innodb

我在努力理解如何编写最好的代码和查询时痛苦地努力

直接提出问题:我是否需要或者是否需要在交易中明确写LOCK IN SHARED MODEFOR UPDATEREAD UNCOMMITTED除外)?

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

1 个答案:

答案 0 :(得分:3)

简短的回答:绝对是的。

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

考虑您正在创建一个Web应用程序,其中您的会话数据存储在数据库中。会话数据时Race condition is a concern。虽然在使用文件存储会话数据时会满足这种担忧,但如果将它们移动到数据库,则有责任确保请求不会覆盖彼此的会话更改。在这种情况下,您需要使用FOR UPDATE从MySQL读取会话数据,以确保其他请求将等待此会话回写会话并提交事务,然后才能读取它。

<强> [UPDATE]

以下是共享模式的用例:

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

<强> [UPDATE]

关于SERIALIZABLE的事务隔离级别,MySQL's documentation非常明确。如果您以这种方式设置事务级别,还有SET autocommit = 0;,那么它与REPEATABLE READ级别完全相同,并且最后用LOCK IN SHARE MODE编写所有选择查询(除非您提及{{1}明确地)。这意味着您将触摸的所有内容(显式或隐式)都将被锁定。那些在没有提及锁定或FOR UPDATE的情况下被选中的那些被锁定在共享模式中,其余的都处于独占模式。