2011-03-23 181 views
4

我很困惑你爲什麼要指定FOR UPDATE - 爲什麼數據庫在意你要用SELECT的數據來做什麼?SELECT ... * FOR UPDATE *的用途是什麼?

編輯:對不起,我問這個問題很差。我知道文檔說,它將事物變成一個「鎖定閱讀」 - 我想知道的是「存在哪些情況下可觀察到的行爲會在指定FOR UPDATE與不指定它之間存在差異 - 也就是說,具體做什麼該鎖意味着

回答

9

http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

它與交易鎖定表做。比方說,你有以下幾種:

START TRANSACTION; 
SELECT .. FOR UPDATE; 
UPDATE .... ; 
COMMIT; 
SELECT語句運行後

,如果從不同的用戶有其他選擇,它不會運行,直到你的第一筆交易命中COMMIT線。

還要注意的是FOR UPDATE之外的交易是沒有意義的。

+0

是的 - 我閱讀文檔 - 但是對於RDBMS的用戶來說,這會做什麼? – 2011-03-23 20:44:13

+0

已更新的答案。 – 2011-03-23 20:48:10

+0

啊 - 這樣可以讓你做一些事情,比如「START TRANSACTION; SELECT MAX(id + 1)as newid FROM thetable FOR UPDATE; INSERT INTO thetable(id)VALUES(newid); COMMIT;' - 你會知道爲MAX()+ 1返回的值不能與其他人衝突嗎? – 2011-03-23 20:51:49

0

它創建一個鎖定讀取,以便沒有人可以更新它,直到完成爲止,例如

SELECT counter_field FROM child_codes FOR UPDATE; 
UPDATE child_codes SET counter_field = counter_field + 1; 

這裏http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

+0

它是如何知道「你什麼時候完成」的? – 2011-03-23 20:43:02

+0

當聲明完成後它完成 – SQLMenace 2011-03-23 20:43:30

+0

咦?聲明以分號結束! (什麼可以在「FOR UPDATE」和分號之間?) – 2011-03-23 20:45:07

0

看到它會鎖住行(或整個表),這樣的行不能在另一個會話併發更新。鎖定一直持續到事務提交或回滾。

1

,這是設計來解決具體的情況是,當你需要閱讀和更新一列中的值。有時你可以逃脫首先更新列(其中鎖定它),然後閱讀它之後,例如:

UPDATE child_codes SET counter_field = counter_field + 1; 
SELECT counter_field FROM child_codes; 

這將返回counter_field的新的價值,但可能是在您的應用程序可以接受的。如果您嘗試重置字段(因此您需要原始值),或者如果您有複雜的計算無法在更新語句中表示,則這是不可接受的。在這種情況下,爲了避免兩個連接競相同時更新同一列,您需要鎖定該行。

如果您的RDBMS不支持FOR UPDATE,那麼你可以通過例如執行無用的更新模擬它

UPDATE child_codes SET counter_field = counter_field; 
SELECT counter_field FROM child_codes; 
UPDATE child_codes SET counter_field = 0;