2012-06-06 136 views
0

我正在爲一個Silverlight應用程序創建一個WCF Web服務,並且我需要在修改時將一條記錄讀取/寫入鎖定。悲觀鎖定記錄?

我正在使用MySQL版本5.5.11。

更具體地說,我想阻止從行中讀取數據的請求,當它被修改時。

兩個SQL的UPDATE命令和SELECT實際上是非常簡單的,是這樣的:

更新(應該鎖定爲讀/寫):

UPDATE user SET user = ..... WHERE id = ..... 

選擇(不應該能夠在閱讀從上面的查詢)鎖定:

SELECT * FROM user WHERE id = ..... 

這裏是我的嘗試,但它似乎不工作或鎖定任何東西:

START TRANSACTION; 
    SELECT user 
    FROM user 
    WHERE id = 'the user id' 
    FOR UPDATE; 

    UPDATE user 
    SET user = 'the user data' 
    WHERE id = 'the user id'; 
COMMIT; 
+1

爲什麼即使在交易中執行此操作? 'UPDATE'獨立運行。也就是說,你所嘗試的應該仍然有效;是什麼讓你覺得它沒有? – eggyal

回答

0

你怎麼確定它沒有鎖定記錄?

當查詢運行在帶有鎖的表上時,它將等待鎖釋放或最終超時。您的更新交易發生得如此之快,以至於您甚至無法分辨出它已被鎖定。

您能夠告訴問題的唯一方法是,如果您有一個查詢在您的事務開始後運行,但返回了用戶的原始值而不是更新的值。發生了什麼事?

我只是把它放在一個評論中,但它太長了,但我會根據你的回答更新一個更完整的答案。

+0

嗨, 應該在我原來的帖子中的SQL查詢也阻止其他查詢從這一行讀取數據? 我的情況似乎發生了什麼事情,即一條記錄正在被修改過程中,另一條記錄能夠從中讀取數據並/或返回舊值。這是一個Web應用程序,不知道它是否重要。 – SlashJ

+0

您的交易將持續一小會兒。另一個查詢甚至能夠在這個小時間內啓動的可能性非常小。也許在更新事務開始之前,返回舊值的查詢已啓動。這聽起來並不像你已經證實,這確實是問題,我的懷疑是你的問題在別處。 –

+0

@Armz此外,我不使用MySQL,所以我不是一個專家如何鎖定,但我認爲你可能會誤解你什麼時候需要使用FOR UPDATE。如果你只更新一個表格,那麼行應該被鎖定,你不需要自己鎖定它們。問題出在您需要時,例如,在釋放表上的鎖之前確保發生多個任務。爲了讓行鎖定在多個更新語句之間,您可以使用FOR UPDATE將它們鎖定在整個時間。但是對於單個更新聲明來說,我認爲這是多餘的,不必要的。 –

0

MySql使用多版本併發控制by default(這是一個非常非常好的行爲,而不是MSSQL)。嘗試使用locking reads(鎖定在分享模式)來實現你想要的。