0

我正在尝试了解 InnoDB 的锁定机制。

假设我有以下 PHP 脚本:

mysql_query('BEGIN;');
$a=mysql_query('SELECT id, status FROM testtable WHERE id=123 LIMIT 1 FOR UPDATE;'); 
$res=mysql_fetch_assoc($a);
$b=somefunction($res['id']);
$c=someotherfunction($b);
mysql_query('UPDATE testtable SET status=1 WHERE id=123;');
mysql_query('COMMIT;');

在 somefunction() 和 someotherfunction() 中,我们将从同一个表中执行许多其他查询,但也来自其他表。它甚至从 id=123 的 testtable 中选择其他字段。

我是否正确地认为在这个会话中我可以使用 id=123 做任何我想做的事情,但其他会话将等待锁被释放?

因为我在第一个查询中使用'for update',所以这是 testtable 中唯一将被锁定的行。在同一会话中选择/更新/插入的任何其他表或行都保持不变(解锁)?

如果 someotherfunction() 选择并更新 id=123 上的不同字段会发生什么?这可能吗?锁能留吗?

4

1 回答 1

0

我不确定锁定部分,但进行事务以允许对一组查询进行“全部或全部”。

例如,如果您要为某种付款运行以下两个查询:

UPDATE customer SET credit=credit - 1 WHERE id=1;
INSERT INTO subscriptions VALUES (...);

例如,如果 INSERT 查询失败,客户的信用会减少,但不会获得订阅。

通过将其包装在事务中,如果查询的任何部分失败,它就会恢复到以前的状态。

BEGIN;
UPDATE customer SET credit=credit - 1 WHERE id=1;
INSERT INTO subscriptions VALUES (...);
COMMIT;

要么两个查询都成功,要么失败时不做任何更改。

编辑:我不相信 InnoDB 会自动为你做任何锁定,查找SELECT ... LOCK IN SHARE MODESELECT ... FOR UPDATE

于 2013-05-12T18:28:53.293 回答