mysql 學習日記 悲觀和樂觀鎖

理解  悲觀鎖就是什麼事情都是須要當心翼翼,生怕弄錯了出大問題,git

通常狀況下 "增刪改" 都是有事務在進行操做的,可是 "查" 是不須要事務操做的,sql

可是凡事沒有例外,好比雙十一購物,不少人搶購一個物品,可是商品總數(假設5個)數據庫

同一時間進行操做,每一個人都能看到物品多少個,都早同一時間下單,可是隻有5個商品,只有5個用戶能過購買到(每人一個購買),其餘人也會顯示出訂單的操做,可是庫存已是爲0沒法購買的行爲(顯示仍是5ge庫存),會給用戶形成很差體驗安全

既讓如此 爲何不讓一個事務鎖定物品的個數修改,而其餘用戶只能查看,並不能下單,當用戶進行updata操做以後釋放鎖,其餘用戶才能根據狀況下單,再次把物品行鎖住(不會出現訂單表交錢了還提示沒庫存)spa

 

 

可能我說的不是很準確,可是悲觀鎖就是一步一步走,若是輪到它則執行則鎖行操做,避免一些問題,通常用在金錢詢,庫存詢等... 版本控制

 

執行sql語句格式code

select money from usercred where id=1 for update;

統一格式在select查詢條件以後增長 for updata (記住查詢條件是索引列纔是鎖行不讓則是鎖表)            查詢操做中除了敏感數據查詢,其餘不須要使用鎖行操做orm

 

整體理解就是 悲觀鎖是一個在有須要求的狀況下查詢語句事務中隔離性最高的ser...  串行,當悲觀鎖鎖住行時,其餘事務只能等待,而且不能讀取該行悲觀數據blog

而且悲觀鎖只能在begin和commit之間執行索引

 




 

樂觀鎖 查詢出須要修改的數據,可是增長一個字段做爲一個版本控制(像git同樣),若是進行修改一塊兒將版本控制的字段一塊兒where做爲條件,若是符合則修改,不符合也沒事,由於數據庫中的數據給其餘事務修改以後,where查詢的條件不符合,因此不會對持久化的數據形成影響

 

例子以下

create table card( id int; money float; version int;                        // 樂觀鎖控制,字段名無所謂 primary key(id);                 // 主鍵 auto increment(id); // 自增加 index(money,version);         // 索引 ); 

建立上面一個表,我使用go的gorm來表達一下操做

type card struct{ Id int                       `gorm:"id"` Money float              `gorm:"money"`     // 默認這個帳戶100元
    Version int               `gorm:"varsion"` } func main(){ var c card if err := db.first(&c).Error():err!=nil{       // 查出一條數據
 panic(err) } err = db.Model(&c).Where("id = ? and varsion = ?",c.Id,c.Version).updata(c.Money + 200 ,c.Version+1).error() if err != nil{ // 說明其餘事務在我執行這個操做時進行了updata commit,我這邊where在數據查詢表沒有出現符合條件的,因此執行失敗
 } fmt.Println("success") } 

樂觀鎖就不是一個事務的操做,是手動建立的一種邏輯來保證數據一致性

根據多個條件來進行控制數據是否和查詢時一致保持安全

比方  a 操做查詢獲得一個數據,其中返回的數據集中含有 money(100)和一個varsion(1),,你對這個數據進行修改,其中money+100,varsion+1 ,可是在你修改尚未提交時,其餘b,c,d..的鏈接也同時和你同樣的操做,而且比你提交commit的速度快,當你使用updata修改語句去根據先前查詢獲得結果尋找數據時,對比version和money,可是已經有其餘提交比你快提交了,找不到a查詢過的數據行(此時時b鏈接提交的數據是money = 300,version=2),因此不會提交,丟棄操做,

樂觀使用一個額外字段保證數據和查詢出時的數據一致纔會更新(更新查詢時查詢的條件要有惟一屬性,不讓更新查詢時出現多個操做不可逆)

 

 

 


 

 

悲觀鎖更加適合轉帳交易業務,樂觀鎖傾向並非對數據要求絕對安全的環境,可是絕對不適用於轉帳交易等敏感地位

 

悲觀鎖和事務區別在於

悲觀鎖會將查詢時就將行鎖住,其餘鏈接操做不能查詢更不能修改,可是也是事務的一種

事務  通常用於增刪改而不用於查的事務管理(雖然也能夠管理查的事務,可是和悲觀鎖同樣差很少,除非時特別需求,否則不會要求對查的操做加鎖)

相關文章
相關標籤/搜索