數據庫鎖如何與連接和會話綁定?
我聽說過頁級和行級鎖,但從未聽說過它們用於會話和連接。今天,我們的 (MySQL) DBA 正在談論行鎖,並暗示可以在連接或會話級別設置它們的範圍。這是真的,還是我誤會了他?
我沒有意識到可以在建立連接時(或在啟動會話時)設置鎖,然後在連接/會話結束時釋放。如果這是真的,那麼這對行/頁級鎖有什麼好處?提前致謝。
如果這是真的,那麼這對行/頁級鎖有什麼好處?
你可能誤解了他的意思。
客戶端連接和會話本質上是一回事。會話在客戶端進行身份驗證後開始,並在客戶端斷開連接時結束。(這些在文件中也稱為執行緒;每個連接/會話通常都有一個專用的伺服器執行緒為其提供服務。)
MySQL 中的所有鎖——行鎖、表鎖和命名鎖(它們是建議性互斥鎖,而不是資料結構鎖)——總是與創建鎖的會話相關聯並由其持有。
以下語句取自表級鎖的 MySQL 文件,但適用於所有鎖:
會話只能為自己獲取或釋放鎖。一個會話不能獲取另一個會話的鎖或釋放另一個會話持有的鎖。
如果沒有顯式釋放,所有鎖總是在持有鎖的會話結束時自動釋放。當客戶端斷開連接、客戶端執行緒被終止或由於到期而超時時,會話結束,無論哪個
interactive_timeout
或多個wait_timeout
計時器適用於會話。所以我懷疑在這些意義上,可以說鎖是“作用於”會話的;但是,鎖的範圍和影響始終是全域的。如果不是這種情況,那麼鎖定就沒有多大意義了——鎖定的存在正是為了防止其他會話做與你的執行緒正在做的事情相衝突的事情。
InnoDB 支持多粒度鎖定,允許記錄鎖和整個表上的鎖共存。為了使多粒度級別的鎖定切實可行,使用了稱為意向鎖的其他類型的鎖。意向鎖是 InnoDB 中的表鎖。意圖鎖背後的想法是讓事務指示稍後對該表中的行需要哪種類型的鎖(共享或獨占)。 — http://dev.mysql.com/doc/refman/5.5/en/innodb-lock-modes.html
這是指
SELECT ... LOCK IN SHARE MODE
(obtains “Intention Shared” row locks) 和SELECT ... FOR UPDATE
(obtains “Intention Exclusive” row locks) 語句,它們確實允許您故意獲取行上的鎖……但是,準確地說,這些不在會話級別——它們更加細化:它們是事務級別,是會話的子集。一旦你COMMIT
或ROLLBACK
目前的交易,這些被釋放。當然,如果您的會話意外終止,事務會回滾,這也會釋放鎖。
在某種程度上,是的。
對於 InnoDB,您可以選擇可以鎖定哪些行。它不是 DB Connection 的特定設置。這是您在執行 UPDATE 之前必須呼叫的特定查詢。
SELECT ... FOR UPDATE
SELECT ... LOCK IN SHARE MODE
這可以根據這些 SELECT 的結果集啟動排他或共享行鎖。
您可以在MySQL 文件中找到更多資訊。
我之前寫過關於使用這些的文章:
Aug 08, 2011
: InnoDB 死鎖是 INSERT/UPDATE/DELETE 獨有的嗎?Jan 02, 2012
:鎖定分享模式Mar 18, 2012
: select for update 在索引列上給出錯誤May 09, 2012
:更新行時事務鎖定超時May 13, 2012
:無法更新 innodb 表中的某些行Aug 10, 2012
; MySQL中類似的函式NOWAIT關於會話和連接
執行
SELECT ... FOR UPDATE
將在您打算更新的行上啟動鎖定,並且仍然允許其他數據庫連接讀取。表演
SELECT ... LOCK IN SHARE MODE
基本上是相反的
- 鎖定行供您閱讀
- 允許相同鎖定行的 SELECT
- 阻止連接執行
SELECT ... FOR UPDATE
或直接 DML我看到使用這些
SELECT
查詢的唯一優勢是防止頁面上不必要的死鎖。我希望這有幫助 !!!