數據庫鎖一般可以分為兩類,一個是悲觀鎖,一個是樂觀鎖。
簡單的來說:
悲觀鎖:顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖:顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。
樂觀鎖一般是指用戶自己實現的一種鎖機制,假設認為數據一般情況下不會造成沖突,所以在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。樂觀鎖的實現方式一般包括使用版本號和時間戳。
悲觀鎖一般就是我們通常說的數據庫鎖機制,悲觀鎖主要表鎖、行鎖、頁鎖。在MyISAM中只用到表鎖,不會有死鎖的問題,鎖的開銷也很小,但是相應的並發能力很差。innodb實現了行級鎖和表鎖,鎖的粒度變小了,並發能力變強,但是相應的鎖的開銷變大,很有可能出現死鎖。同時inodb需要協調這兩種鎖,算法也變得復雜。InnoDB行鎖是通過給索引上的索引項加鎖來實現的,只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖。
表鎖和行鎖都分為共享鎖和排他鎖(獨占鎖),而更新鎖是為了解決行鎖升級(共享鎖升級為獨占鎖)的死鎖問題。