mysql'FOR UPDATE'命令无法正常工作

时间:2013-04-29 07:55:44

标签: php mysql

我有两个php页面,page1.php&使page2.php

page1.php中

execute_query('START TRANSACTION');
$res =execute_query('SELECT * FROM table WHERE id = 1 FOR UPDATE');

sleep(20);

print $res->first_name;
execute_query('COMMIT');

print"\n OK";

使page2.php

 $res =execute_query('SELECT * FROM table WHERE id = 1');
print $res->first_name;

我几乎同时执行两个页面

因此根据mysql的'FOR UPDATE'条件,page2.php中的结果将仅在执行page1.php之后显示(即在page1.php中显示'OK'之后),因为两个页面都读取相同的行。

但正在发生的事情是,

page2.php突然显示结果,甚至在完成page1.php

的执行之前

我知道'FOR UPDATE'命令有什么问题。?

2 个答案:

答案 0 :(得分:2)

我假设该表格为InnoDB(不是MyISAMMEMORY)。 您在交易中使用SELECT。我不知道你的隔离级别,但我猜你的交易没有相互阻塞。

有关详情,请参阅此页:http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html

修改

我将按要求更好地解释这个概念。隔离级别是会话/全局变量,用于确定执行事务的方式。某些隔离级别在尝试修改同一行时阻止其他事务,但某些隔离级别不会。

例如,如果您使用UNCOMMITTED,则它不会阻止任何内容,因为您访问行的实际版本(在事务结束之前可能会过时)。另一个SELECT(第2页)只读取表,因此不必等待第一个事务结束。

SERIALIZABLE更加安全。它不是默认值,因为它是最慢的隔离级别。如果您正在使用它,请确保FOR UPDATE仍然适合您。

答案 1 :(得分:0)

我认为您的SELECT FOR UPDATE位于BEGIN TRANSACTION内,因此在COMMIT语句到达之前它不会锁定记录,并且您使用sleep(20)延迟执行。所以page2.php将被执行。