數據庫樂觀鎖和悲觀鎖的理解和實現


數據的鎖定分為兩種,第一種叫作悲觀鎖,第二種叫作樂觀鎖。

1、悲觀鎖,就是對數據的沖突采取一種悲觀的態度,也就是說假設數據肯定會沖突,所以在數據開始讀取的時候就把數據鎖定住。【數據鎖定:數據將暫時不會得到修改】

2、樂觀鎖,認為數據一般情況下不會造成沖突,所以在數據進行提交更新的時候,才會正式對數據的沖突與否進行檢測,如果發現沖突了,則讓用戶返回錯誤的信息。讓用戶決定如何去做。

 

理解:

1. 樂觀鎖是一種思想,具體實現是,表中有一個版本字段,第一次讀的時候,獲取到這個字段。處理完業務邏輯開始更新的時候,需要再次查看該字段的值是否和第一次的一樣。如果一樣更新,反之拒絕。

之所以叫樂觀,因為這個模式沒有從數據庫加鎖。

2. 悲觀鎖是讀取的時候為后面的更新加鎖,之后再來的讀操作都會等待。這種是數據庫鎖

樂觀鎖優點程序實現,不會存在死鎖等問題。他的適用場景也相對樂觀。阻止不了除了程序之外的數據庫操作。

悲觀鎖是數據庫實現,他阻止一切數據庫操作。

再來說更新數據丟失,所有的讀鎖都是為了保持數據一致性。樂觀鎖如果有人在你之前更新了,你的更新應當是被拒絕的,可以讓用戶從新操作。悲觀鎖則會等待前一個更新完成。這也是區別。具體業務具體分析

 

 

實現:

一、悲觀鎖
    1、排它鎖,當事務在操作數據時把這部分數據進行鎖定,直到操作完畢后再解鎖,其他事務操作才可操作該部分數據。這將防止其他進程讀取或修改表中的數據。

    2、實現:大多數情況下依靠數據庫的鎖機制實現

     一般使用 select ...for update 對所選擇的數據進行加鎖處理,例如select * from account where name=”Max” for update, 這條sql 語句鎖定了account 表中所有符合檢索條件(name=”Max”)的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。

二、樂觀鎖
    1、如果有人在你之前更新了,你的更新應當是被拒絕的,可以讓用戶重新操作。

    2、實現:大多數基於數據版本(Version)記錄機制實現

     具體可通過給表加一個版本號或時間戳字段實現,當讀取數據時,將version字段的值一同讀出,數據每更新一次,對此version值加一。當我們提交更新的時候,判斷當前版本信息與第一次取出來的版本值大小,如果數據庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認為是過期數據,拒絕更新,讓用戶重新操作。

三、ORM框架中悲觀鎖樂觀鎖的應用

     一般悲觀鎖、樂觀鎖都需要都通過sql語句的設定、數據的設計結合代碼來實現,例如樂觀鎖中的版本號字段,單純面向數據庫操作,是需要自己來實現樂觀鎖的,簡言之,也就是版本號或時間戳字段的維護是程序自己維護的,自增、判斷大小確定是否更新都通過代碼判斷實現。數據庫進提供了樂觀、悲觀兩個思路進行並發控制。

     對於常用java 持久化框架,對於數據庫的這一機制都有自己的實現,以Hibernate為例,總結一下ORM框架中悲觀鎖樂觀鎖的應用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM