我有以下情形:
「FOR UPDATE」 V/S「鎖定共享模式」:允許併發線程讀取鎖定行的更新「狀態」值
- 用戶X登錄到應用來自位置lc1:打電話Ulc1
- 用戶X(已被黑客入侵,或者他的某個朋友知道他的登錄憑據,或者他只是從他的機器上的其他瀏覽器登錄,等等)。從位置lc2同時登錄:呼叫Ulc2
我使用的是主要的servlet其中:
- 會從數據庫彙集
連接 - 設置自動提交虛假
- 執行,通過應用層進了命令:如果一切順利,設置自動提交到真正的「最後「聲明,並關閉連接。否則,如果發生異常,則使用rollback()。
在我的數據庫(mysql/innoDb)我有一個「歷史」表,與行列:
id(主鍵)|用戶名|日期|主題|鎖定
列「鎖定」的默認值爲「false」,它用作標記特定行是否被鎖定的標誌。
每一行是特定於用戶(如u可以從用戶名欄中看到)
所以回到場景:
- > ULC1從數據庫發送命令到更新他的歷史記錄日期「 D「和主題」T「。
- >從ULC2在確切同時分貝爲相同日期「d」和相同主題「T」發送相同命令更新歷史。
我想要實現的MySQL的/ InnoDB的鎖定系統,使任何一個線程到達做以下檢查:
是列「鎖定」此行真的還是假的?
- 如果爲true,返回一個消息給用戶
- 如果不是真(即未鎖定)「他已經從另一個位置更新相同的數據」:將其標記爲鎖定和更新,然後復位鎖定假一次完成。
這兩種mysql鎖定技術中的哪一種會真正允許第二個到達的線程讀取鎖定列的「更新」值來決定採取的wt操作?
我應該使用「FOR UPDATE」或「LOCK IN SHARE MODE」?
這種情況說明了什麼我要完成:
- ULC1線程到達第一:列「鎖定」是假的,將其設置爲true,並繼續更新過程
- ULC2線程到達而ULC1的交易仍在進行中,並即使該行通過innoDb功能被鎖定,也不必等待,但實際上讀取了「鎖定」列的「新」值,即「真」,因此事實上不必等到Ulc1事務提交讀取「鎖定」列的值(到那時爲止該列的值已經被重置爲假)。
我對2種鎖定機制並不是非常有經驗,到目前爲止我的理解是鎖定共享模式允許其他事務讀取鎖定的行,而FOR UPDATE甚至不允許讀取。但是這個讀取得到更新的值嗎?或第二個到達的線程必須等待第一個線程提交然後讀取值?
任何關於哪種鎖定機制用於這種情況的建議值得讚賞。
另外,如果有更好的方法來檢查行是否被鎖定(除了使用真/假列標誌),請讓我知道它。
謝謝
SOLUTION (基於的jdbc僞例如@ Darhazer的答案)
表:[ID(主鍵)|用戶名|日期|主題|鎖定]
connection.setautocommit(false);
//transaction-1
PreparedStatement ps1 = "Select locked from tableName for update where id="key" and locked=false);
ps1.executeQuery();
//transaction 2
PreparedStatement ps2 = "Update tableName set locked=true where id="key";
ps2.executeUpdate();
connection.setautocommit(true);// here we allow other transactions threads to see the new value
connection.setautocommit(false);
//transaction 3
PreparedStatement ps3 = "Update tableName set aField="Sthg" where id="key" And date="D" and topic="T";
ps3.executeUpdate();
// reset locked to false
PreparedStatement ps4 = "Update tableName set locked=false where id="key";
ps4.executeUpdate();
//commit
connection.setautocommit(true);
THX對您有所幫助。但是我沒有得到你提到第二個線程的部分:你的意思是第二個線程能夠在線程1解鎖記錄之前讀取鎖定的更新值。 – shadesco 2012-02-02 13:57:44
@shadesco當你已經將它標記爲真時,這個想法並不是鎖定已鎖定的值。記錄被鎖定。將數據庫中的鎖定時間保持在最小值並在應用程序中執行(如果您鎖定整個事務處理時間的記錄,則根本沒有必要具有「鎖定」值)。您也可以鎖定記錄,但在將更改提交到鎖定列後,其他事務將看到新值。 – 2012-02-02 15:11:11
我想我明白了你的意思,但是我寫了一個小小的更新部分,附有一個問題給你,你可以檢查一下嗎? – shadesco 2012-02-02 16:23:30