什麼是MySQL(或任何RDBMS)中的鎖定以及何時使用它?帶一個例子的外行人解釋會很棒!什麼是MySQL中的鎖定以及何時使用它?
回答
我們有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
你應該學會這些,並瞭解他們是適用的場景。
謝謝@Chris Diver很好的解釋!我現在明白了;-) – Imran 2010-07-28 16:46:41
前幾天我回答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
。如果兩個會話都插入一行id
的MAX(id) + 1
,則兩者都會插入id = 4
。您可以在沒有FOR UPDATE
位的情況下模擬相同的測試,看看如何在沒有鎖的情況下處理這個問題。
鎖定對於避免兩個用戶同時修改數據至關重要。您可能認爲這不太可能,但根據應用程序的不同,如果相同的數據經常被不同的用戶更改,則存在重大風險。
想象一下以下情況不使用鎖:約翰打開了他的屏幕(他不知道他用的數據庫,他只是誰在看一個漂亮的屏幕終端用戶),修改一些數據,然後點擊「保存」。假設John在9:30開啓屏幕,然後在9:32保存數據。
但是,瑪麗在9:29開了完全相同的屏幕和相同的記錄。那時她看到約翰在9點30分做過的數據。然後,她更新記錄,並在9:31點擊「保存」。
什麼數據被保存?約翰的還是瑪麗的?
瑪麗高興地繼續研究其他記錄,當她回來後再次打開記錄時,她發現她的變化已經消失,她看到了約翰的變化!
請注意,鎖定必須明智地使用,以防止出現意想不到的副作用。例如,假設您的程序在每次打開它進行更改時鎖定記錄。如果約翰鎖定記錄,並且讓他的會話屏幕打開吃午飯或他失去聯繫,會發生什麼?鎖可以長時間保持在那裏,鎖定和不可更改,同時禁止其他人更改(甚至查看)該記錄。其他考慮因素可能是性能,因爲數據庫鎖定和解鎖記錄的時間可能對於大量事務變得明顯。
理解鎖定對維護用戶和數據的完整性至關重要。請看文檔。
感謝@luiscolorado這真的有所幫助:-) – Imran 2010-07-28 16:47:54
版本化數據將是您描述的用例的更好解決方案。你無法真正保持這麼長時間的鎖定......我要做的是,當John保存時,閱讀data +版本,將它們與你顯示的用戶進行比較,然後對檢查數據執行UPDATE對於你剛剛在兩分鐘前閱讀的版本。如果版本不一樣,這意味着其他人觸摸了您的數據 - 您必須刷新它。 – ripper234 2010-11-30 20:33:34
@ ripper234:這就是爲什麼我說鎖定需要多種考慮才能達到最佳方法。你解釋的情況是正確的,你的建議很好。我不打算也不可能在這裏對這個概念進行完整的討論。目的是提供一個簡單的,外行的答案。 – luiscolorado 2012-02-08 12:03:07
- 1. 什麼是MySql工作臺以及我們使用它的目的是什麼?
- 2. activeandroid中的mId是什麼以及它何時可以爲null?
- 3. 什麼是ICustomTypeDescriptor以及何時使用它?
- 4. 什麼是對接框架以及何時使用它?
- 5. 什麼是Request.InputStream以及何時使用它?
- 6. 什麼是curl選項CURLOPT_INTERFACE以及何時使用它?
- 7. 是什麼@「//」做childWithName以及何時使用它
- 8. 代表什麼是代表以及何時使用它?
- 9. Android什麼是setLevel()以及何時應該使用它?
- 10. 什麼是IntelliJ中的「手錶」以及如何使用它們?
- 11. phonegap中的插件是什麼以及如何使用它?
- 12. HTML5中的內容是什麼?以及如何使用它?
- 13. 什麼是OpenEJB中的@Module註釋以及如何使用它?
- 14. AngularJs Material中的defaultIconSet()是什麼以及我如何使用它?
- 15. MySQL中的「無符號」意味着什麼以及何時使用它?
- 16. 什麼是合同類以及它是如何使用的
- 17. 什麼是Flash .SWC文件以及它是如何使用的?
- 18. typedef void(* MyCallback):它是什麼以及如何使用它?
- 19. Magento XMLConnect ...它是什麼以及如何使用它?
- 20. ObjectSpace - 它是什麼以及人們如何使用它?
- 21. Plist:它是什麼以及如何使用它
- 22. 什麼是InputStream和輸出流?爲什麼以及何時使用它們?
- 23. 什麼是切換按鈕以及我們什麼時候可以使用它?
- 24. 什麼是(void(**)())以及如何typedef它?
- 25. 什麼是__printf_fp()以及何時調用?
- 26. 什麼是Ext.Component.initialConfig,它做了什麼,以及在什麼情況下使用它?
- 27. 什麼是片段URL以及爲什麼要使用它
- 28. 什麼是.inc以及爲什麼要使用它?
- 29. 什麼是armeabi以及他們爲什麼使用它
- 30. 什麼是JavaScript中的數組文字符號以及何時使用它?
這對於併發用戶是一個有用的優化:http://www.devshed.com/c/a/MySQL/MySQL-Optimization-part-2/ – 2010-07-28 14:04:38
我認爲你應該接受@Chris的答案。 – ripper234 2010-11-30 20:34:17