2013-05-12 57 views
0

我想了解InnoDB的鎖定機制。請幫我理解MySQL 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的測試表中選擇其他字段。

我是否明白,在本次會議中,我可以做任何我想要的id = 123,但其他會話將等待鎖被釋放?

因爲我在第一個查詢中使用'for update',這是測試表中唯一被鎖定的行。在同一會話中選中/更新/插入的任何其他表或行都保持不變(解鎖)?

如果someotherfunction()選擇並更新id = 123上的不同字段會發生什麼?這可能嗎?鎖持續嗎?

回答

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