在使用InnoDB存儲引擎的Web應用程序中,我無法在以下情況下充分利用數據庫鎖定。如何實現基於數據庫鎖定的防止重複的保護
有3個表格,我會稱它們爲aa
,ar
和ai
。
aa
擁有基本記錄,讓我們說文章。 ar
保存與每個aa
記錄有關的信息,並且aa
和ar
之間的關係是1:m
。
ar
的記錄存儲在aa
的記錄被讀取時第一次被存儲。問題是當兩個請求在(幾乎)相同時從aa
(它還沒有將其相關記錄存儲在ar
中)讀取記錄時發起,ar
記錄被複制。
下面是一個僞代碼,以幫助瞭解情況:
閱讀要求
aa
記錄。掃描
ar
表以確定給定的aa
記錄是否已存儲任何內容。 (假設它沒有。)請參閱
ai
以便找出在給定的aa
記錄中要存儲在ar
中的內容。 (ai
似乎有點風馬牛不相及,但我發現它也有參與鎖定...可能是錯誤的。)插入幾行
ar
這裏是我想達到的目標:
- 閱讀請求的
aa
記錄。
使用或不使用交易,LOCK ar
,所以任何後續請求試圖讀取ar
將等待AT這一點直到這個順序完成。
掃描
ar
表,以發現如果給定aa
記錄已經存儲了什麼。 (假設它沒有。)問題是,如果有兩個同時發生的請求,兩個發現對於給定的aa
記錄在ar
中沒有記錄,並且它們都繼續插入相同的行兩次。否則,如果存在,則會中斷此序列並且不會發生INSERT。諮詢
ai
爲了找出在給定的aa
記錄中要存儲在ar
中的內容。 (ai
似乎有點不相關,但我發現它也必須參與鎖定...可能是錯誤的。)插入幾行
ar
解除鎖定ON ar
似乎很簡單,我是在避免重複失敗。我正在測試Bash shell中一個簡單命令的同時請求(使用wget)。
我已經花了一段時間學習如何鎖定InnoDB引擎在這裏http://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html和這裏http://dev.mysql.com/doc/refman/5.5/en/innodb-locking-reads.html如何工作,並嘗試了幾種方法來利用鎖,仍然沒有運氣。
我希望整個ar
表被鎖定(因爲我想阻止來自多個請求的INSERT發生)導致進一步嘗試與此表交互以等待,直到第一個鎖被釋放。但是隻有一處提到「整個表」被鎖定在文檔中(第一個鏈接頁面中的「意圖鎖定」部分),但沒有進一步討論,或者我無法知道如何實現它。
任何人都可以指出正確的方向嗎?
感謝您的提示,並看似親水平的答覆。我馬上給它一下,如果它有效,就更新你。 – marekful 2014-10-16 20:00:10
當然(雖然問題已經太長了),但真實的生活情況要複雜得多,而且在請求過程中涉及許多其他查詢。到目前爲止,我遇到了'一般錯誤:2014無法執行查詢,而其他未緩衝的查詢處於活動狀態',但不會放棄,這似乎是要走的路。 – marekful 2014-10-16 20:15:33
@MarcellFülöp,你可能喜歡閱讀我的回答[MySQL的錯誤原因2014無法執行查詢,而其他未緩衝的查詢處於活動狀態](http://stackoverflow.com/questions/17434102/causes-of-mysql-error-2014 -cannot-execute-queries-while-other-unbuffered-queries/17582620#17582620) – 2014-10-16 21:47:52