為什麼需要鎖
在併發環境下,如果多個客戶端訪問同一條資料,此時就會產生資料不一致的問題,如何解決,通過加鎖的機制,常見的有兩種鎖,樂觀鎖和悲觀鎖,可以在一定程度上解決併發訪問。
樂觀鎖樂觀鎖,顧名思義,對加鎖持有一種樂觀的態度,即先進行業務操作,不到最後一步不進行加鎖,"樂觀"的認為加鎖一定會成功的,在最後一步更新資料的時候在進行加鎖,樂觀鎖的實現方式一般為每一條資料加乙個版本號,具體流程是這樣的:
1)、建立一張表時新增乙個version欄位,表示是版本號,如下:
2)、修改資料的時候首先把這條資料的版本號查出來,update時判斷這個版本號是否和資料庫裡的一致,如果一致則表明這條資料沒有被其他使用者修改,若不一致則表明這條資料在操作期間被其他客戶修改過,此時需要在**中拋異常或者回滾等。偽**如下:
updatetbsetname='yyy'andversion=version+1whereid=1andversion=version;
1. select name as old_name, version as old_version from tb where ...;
2. 根據獲取的資料進行業務操作,得到new_dname和new_version
3.update set name = new_name, version = new_version where version = old_version
if(updated row >) else{
// 樂觀鎖獲取失敗,回滾並重試
update其實在不在事物中都無所謂,在內****的:update是單執行緒的,及如果乙個執行緒對一條資料進行update操作,會獲得鎖,其他執行緒如果要對同一條資料操作會阻塞,直到這個執行緒update成功後釋放鎖。
另外,樂觀鎖不需要資料庫底層的支援!!!
悲觀鎖正如其名字一樣,悲觀鎖對資料加鎖持有一種悲觀的態度。因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)。
首先我們需要set autocommit=0,即不允許自動提交
用法:select * from tablename where id = 1for update;
申請前提:沒有執行緒對該結果集中的任何行資料使用排他鎖或共享鎖,否則申請會阻塞。
for update僅適用於innodb,且必須在事務塊(begin/commit)中才能生效。在進行事務操作時,通過「for update」語句,mysql會對查詢結果集中每行資料都新增排他鎖,其他執行緒對該記錄的更新與刪除操作都會阻塞。排他鎖包含行鎖、表鎖。
假設有一張商品表 shop,它包含 id,商品名稱,庫存量三個字段,表結構如下:
插入如下資料:
併發導致資料一致性的問題:
如果有a、b兩個使用者需要購買id=1的商品,ab都查詢商品數量是1000,a購買後修改商品的數量為999,b購買後修改數量為999。
用樂觀鎖的解決方案:
每次獲取商品時,不對該商品加鎖。在更新資料的時候需要比較程式中的庫存量與資料庫中的庫存量是否相等,如果相等則進行更新,反之程式重新獲取庫存量,再次進行比較,直到兩個庫存量的數值相等才進行資料更新。偽**如下:
悲觀鎖方案:
每次獲取商品時,對該商品加排他鎖。也就是在使用者a獲取獲取 id=1 的商品資訊時對該行記錄加鎖,期間其他使用者阻塞等待訪問該記錄。悲觀鎖適合寫入頻繁的場景。**如下:
我們可以看到,首先通過begin開啟乙個事物,在獲得shop資訊和修改資料的整個過程中都對資料加鎖,保證了資料的一致性。
MySql中的樂觀鎖與悲觀鎖
mysql 悲觀鎖 樂觀鎖 悲觀鎖與樂觀鎖是兩種常見的資源併發鎖設計思路,也是併發程式設計中乙個非常基礎的概念。本文將對這兩種常見的鎖機制在資料庫資料上的實現進行比較系統的介紹。悲觀鎖 pessimistic lock 悲觀鎖的特點是先獲取鎖,再進行業務操作,即 悲觀 的認為獲取鎖是非常有可能失敗的...
MySQL中的樂觀鎖與悲觀鎖
在併發控制程式設計中鎖是乙個非常重要的概念,鎖對於資料和業務一致性的保證起到關鍵作用,鎖可以是程式層面的,也可以是資料庫層面的,今天本文就通過mysql來說明悲觀鎖與樂觀鎖兩種常見的鎖機制。悲觀鎖 悲觀鎖 pessimistic lock 的特點是先獲取鎖,在進行資料操作,最後釋放鎖。即先鎖後查再更...
mysql悲觀鎖與樂觀鎖
pessimistic locking 樂觀併發控制 樂觀鎖 和悲觀併發控制 悲觀鎖 是併發控制主要採用的技術手段。悲觀鎖還是樂觀鎖,都是人們定義出來的概念,是一種思想。對於資料庫 悲觀鎖 在資料處理過程,將資料處於鎖定狀態,一般使用資料庫的鎖機制實現。從廣義上來講,前面提到的行鎖 表鎖 讀鎖 寫鎖...