1. 程式人生 > >什麼是樂觀鎖與悲觀鎖?

什麼是樂觀鎖與悲觀鎖?

樂觀鎖:
簡單的來說:就是認為別人不會過來修改它的資料,常見的樂觀鎖通常會帶一個version(版本),等到提交的時候,會去檢查一下版本,如果版本修改了,就會丟擲異常,並且回滾資料;

樂觀鎖通常需要在表中額外設計一個version的冗餘欄位

並且在插入資料的時候,將version初始化為0

常見的樂觀鎖如下,注意version

   <update id="updateBasicInfo">
     update `user_info`
    set version = version + 1,
      bit_state = #{bitState},
phone_number = #{phoneNumber}, real_auth_id = #{realAuthId}, marriage_id = #{marriage.id}, kid_count_id = #{kidCount.id}, education_background_id = #{educationBackground.id}, house_condition_id = #{houseCondition.id}, income_grade_id = #{incomeGrade.id} where
id = #{id} and version = #{version} </update>
在Service層,一但修改失敗,就可以丟擲異常了,通常是“伺服器忙,請稍後再試”

悲觀鎖:
簡單的來說就是:認為誰都會過來修改它的資料,所以無論在做什麼操作的時候,都會加把鎖,等自己操作完成之後,才會將鎖放開

與樂觀鎖依靠程式設計師自己實現不同的是,悲觀鎖是依靠資料庫自帶的鎖機制實現的

資料庫中(僅僅以MySQL為例)常見的鎖有

  • 表鎖

  • 共享鎖

  • 行鎖

    表鎖很簡單:

begin;
select * from ip_log for
update

這個表鎖很簡單,在Navicat中再啟動個命令介面,發現無論是update或者是insert都處於等待狀態

除非commit不然無法進行下一步操作

共享鎖:

begin;
select * from user where id = 1 lock in share mode;

共享鎖沒什麼好說的,但是需要注意的是:

update,insert操作是不能加共享鎖的,因為update,insert,delete自帶排他鎖,加了會報語法錯誤

mysql> update user set name = 'kiki' where id = 7 lock in share mode;
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lock in share mode' at line 1

行鎖

begin;
select * from user where id = 1 lock in share mode;*

這樣就能給id = 1加上行鎖了