2010-07-28 57 views
10

什麼是MySQL(或任何RDBMS)中的鎖定以及何時使用它?帶一個例子的外行人解釋會很棒!什麼是MySQL中的鎖定以及何時使用它?

+0

這對於併發用戶是一個有用的優化:http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-2/ – 2010-07-28 14:04:38

+0

我認爲你應該接受@Chris的答案。 – ripper234 2010-11-30 20:34:17

回答

9

我們有200 $

我去ATM,把我的卡插入機器時,機器會檢查我的$ 200

的平衡。同時,你去一個平衡的合資銀行賬戶進入銀行並要求50美元,出納員開着你的賬戶並確認你有錢。

我要求的$ 200提款,機器計算我的錢給我200 $,並設置我的餘額$ 0

櫃員計算你的錢,給你$ 50,系統然後更新的帳戶餘額150美元(200美元--50美元撤銷)。

所以現在我們有250美元的現金和150美元的賬戶。 200美元的利潤。

數據庫應該使用鎖來防止兩個事務同時發生。

問題是如果您以這種方式處理每個事務,那麼我們將失去併發性並且性能會受到影響,因此根據場景使用不同的transaction isolation levels,例如,您可能不在意某人可以修改數據已在交易中閱讀。

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

你應該學會這些,並瞭解他們是適用的場景。

+0

謝謝@Chris Diver很好的解釋!我現在明白了;-) – Imran 2010-07-28 16:46:41

3

前幾天我回答a question on SO,給這表明的情況下locking允許多個用戶同時插入表中的行和遞增id,而無需使用AUTO_INCREMENT一個例子。

考慮以下方案爲例:

CREATE TABLE demo_table (id int) ENGINE=INNODB; 

-- // Add few rows 
INSERT INTO demo_table VALUES (1), (2), (3); 

然後我們可以做到以下幾點:

START TRANSACTION; 

-- // Get the MAX(id) so that we increment it by one 
SELECT @x := MAX(id) FROM your_table FOR UPDATE; 

+---------------+ 
| @x := MAX(id) | 
+---------------+ 
|    3 | 
+---------------+ 
1 row in set (0.00 sec) 

FOR UPDATE語法是什麼其實是把對這個查詢讀取行上的鎖。

沒有提交事務,我們開始另一個單獨的會話(模擬併發用戶),並執行相同的:

START TRANSACTION; 

-- // Get the MAX(id) as well 
SELECT MAX(id) FROM demo_table FOR UPDATE; 

數據庫將等到鎖前一交易日設置運行此之前發佈查詢。

因此切換到上屆會議上,我們可以插入新行並提交事務:

-- // Insert a new row with id = MAX(id) + 1 
INSERT INTO demo_table VALUES (@x + 1); 

COMMIT; 

後的第一屆會議提交事務,鎖將被解除,並在第二屆查詢返回:

+---------+ 
| MAX(id) | 
+---------+ 
|  4 | 
+---------+ 
1 row in set (8.19 sec) 

注意,如果沒有鎖定,第二屆會議會立即返回,但3作爲MAX(id)而不是4。如果兩個會話都插入一行idMAX(id) + 1,則兩者都會插入id = 4。您可以在沒有FOR UPDATE位的情況下模擬相同的測試,看看如何在沒有鎖的情況下處理這個問題。

6

鎖定對於避免兩個用戶同時修改數據至關重要。您可能認爲這不太可能,但根據應用程序的不同,如果相同的數據經常被不同的用戶更改,則存在重大風險。

想象一下以下情況使用鎖:約翰打開了他的屏幕(他不知道他用的數據庫,他只是誰在看一個漂亮的屏幕終端用戶),修改一些數據,然後點擊「保存」。假設John在9:30開啓屏幕,然後在9:32保存數據。

但是,瑪麗在9:29開了完全相同的屏幕和相同的記錄。那時她看到約翰在9點30分做過的數據。然後,她更新記錄,並在9:31點擊「保存」。

什麼數據被保存?約翰的還是瑪麗的?

瑪麗高興地繼續研究其他記錄,當她回來後再次打開記錄時,她發現她的變化已經消失,她看到了約翰的變化!

請注意,鎖定必須明智地使用,以防止出現意想不到的副作用。例如,假設您的程序在每次打開它進行更改時鎖定記錄。如果約翰鎖定記錄,並且讓他的會話屏幕打開吃午飯或他失去聯繫,會發生什麼?鎖可以長時間保持在那裏,鎖定和不可更改,同時禁止其他人更改(甚至查看)該記錄。其他考慮因素可能是性能,因爲數據庫鎖定和解鎖記錄的時間可能對於大量事務變得明顯。

理解鎖定對維護用戶和數據的完整性至關重要。請看文檔。

+0

感謝@luiscolorado這真的有所幫助:-) – Imran 2010-07-28 16:47:54

+0

版本化數據將是您描述的用例的更好解決方案。你無法真正保持這麼長時間的鎖定......我要做的是,當John保存時,閱讀data +版本,將它們與你顯示的用戶進行比較,然後對檢查數據執行UPDATE對於你剛剛在兩分鐘前閱讀的版本。如果版本不一樣,這意味着其他人觸摸了您的數據 - 您必須刷新它。 – ripper234 2010-11-30 20:33:34

+2

@ ripper234:這就是爲什麼我說鎖定需要多種考慮才能達到最佳方法。你解釋的情況是正確的,你的建議很好。我不打算也不可能在這裏對這個概念進行完整的討論。目的是提供一個簡單的,外行的答案。 – luiscolorado 2012-02-08 12:03:07

相關問題