请帮我理解MySQL InnoDB交易

时间:2013-05-12 18:16:40

标签: php mysql locking innodb commit

我正在尝试了解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()中我们会从同一个表中执行很多其他查询,但也会从其他表中执行。它甚至从testtable中选择其他字段,其中id = 123。

我能说得对吗在这个会话中我能用id = 123做我想做的事,但是其他会话会等待锁被释放吗?

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

如果someotherfunction()选择并更新id = 123上的其他字段,会发生什么?这可能吗?锁是否留下来?

1 个答案:

答案 0 :(得分: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