10

我对你为什么要指定感到困惑FOR UPDATE——为什么数据库关心你要如何处理来自SELECT?

编辑:对不起,我问得不好。我知道文档说它把事情变成了“锁定读取”——我想知道的是“存在哪些情况下可观察的行为在指定FOR UPDATE和不指定之间会有所不同——也就是说,具体是做什么的锁需要?

4

5 回答 5

17

http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

它与在事务中锁定表有关。假设您有以下内容:

START TRANSACTION;
SELECT .. FOR UPDATE;
UPDATE .... ;
COMMIT;

在 SELECT 语句运行后,如果您有另一个来自不同用户的 SELECT,它不会运行,直到您的第一个事务到达 COMMIT 行。

还要注意,FOR UPDATE在事务之外是没有意义的。

于 2011-03-23T20:42:25.610 回答
3

这旨在解决的特定情况是当您需要读取和更新列中的值时。有时您可以先更新列(锁定它)然后再读取它,例如:

UPDATE child_codes SET counter_field = counter_field + 1;
SELECT counter_field FROM child_codes;

这将返回 counter_field 的新值,但这在您的应用程序中可能是可以接受的。如果您尝试重置该字段(因此您需要原始值),或者您有一个无法在更新语句中表达的复杂计算,那么这是不可接受的。在这种情况下,为了避免两个连接竞相更新同一列,您需要锁定该行。

如果您的 RDBMS 不支持 FOR UPDATE 那么您可以通过执行无用的更新来模拟它,例如

UPDATE child_codes SET counter_field = counter_field;
SELECT counter_field FROM child_codes;
UPDATE child_codes SET counter_field = 0;
于 2011-03-23T20:58:24.677 回答
1

SELECT FOR UPDATE 告诉 RDBMS 您要锁定这些行,以便在您更新并提交或回滚并解锁它们之前,其他人无法访问它们:

http://www.techonthenet.com/oracle/cursors/for_update.php

于 2011-03-23T20:41:39.650 回答
0

它创建一个锁定读取,这样在你完成之前没有人可以更新它,例如

SELECT counter_field FROM child_codes FOR UPDATE;
UPDATE child_codes SET counter_field = counter_field + 1;

见这里http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

于 2011-03-23T20:42:02.820 回答
0

它将锁定行(或整个表),以便行不能在另一个会话中同时更新。锁定一直保持到事务提交或回滚为止。

于 2011-03-23T20:42:11.600 回答