我正在尝试了解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上的其他字段,会发生什么?这可能吗?锁是否留下来?
答案 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 MODE
和SELECT ... FOR UPDATE