悲觀鎖
它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個數據處理過程中,將數據處於鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)。
最佳實踐
具體示例請參照MySQL的悲觀鎖實現
樂觀鎖
樂觀鎖機制采取了更加寬松的加鎖機制。悲觀鎖大多數情況下依靠數據庫的鎖機制實現,以保證操作最大程度的獨占性。但隨之而來的就是數據庫 性能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。相對悲觀鎖而言,樂觀鎖更傾向於開發運用。
最佳實踐
首先創建一張表。
mysql> CREATE TABLE optimistic_lock(id INT PRIMARY KEY, name CHAR(20), version TIMESTAMP);
TIMESTAMP類型有個特性,就是數據一旦有增改就會自動變化。
然后向表里插入三條數據。
mysql> INSERT INTO optimistic_lock(id, name) VALUES(1, '張三'),(2, '李四'),(3, '王五');
目前數據是這樣的。
下面開始模擬在多線程下進行數據更新:
程序A讀取id為1的數據,其中version字段值為2017-12-23 02:27:25。
這時程序B也讀取id為1的數據,其中version字段值也為2017-12-23 02:27:25。
mysql> SELECT version FROM optimistic_lock WHERE id = 1;
程序A開始更新id為1的數據的name字段為劉勇。
mysql> UPDATE optimistic_lock SET name = '劉勇' WHERE id = 1 AND version = '2017-12-23 02:27:25';
這里與平時唯一不同的地方就是我將version字段也當做更新條件。
我們可以查看一下更新結果:
name字段已經變為劉勇,而根據TIMESTAMP類型的特性也改變了時間戳。
這時程序B對id為1的數據的name字段進行更新。
mysql> UPDATE optimistic_lock SET name = '王亮' WHERE id = 1 AND version = '2017-12-23 02:27:25';
我們也看一下更新結果:
數據沒有更新,因為version字段已經匹配不上了。
優缺點
相比悲觀鎖的長事務阻塞,樂觀鎖實現了數據自有讀取更新,提高了讀寫效率和並發量。但缺點也很明顯,誰先更新數據誰就可以獲得成功,這樣的無序也源於樂觀鎖的開放性。
本文索引關鍵字:
樂觀鎖:http://www.cnblogs.com/huanStephen/p/8094017.html#o_lock
歡迎大家索引!