MySQL 在高併發下的 訂單撮合 系統使用 共享鎖 與 排他鎖 保證數據一致性

場景描述

高併發的業務常見是有不少種類的,最多見的例如秒殺搶購。它們都有一個共同的特色就是數據更新都比較頻繁,一般涉及到多張業務表的增改操做,且表格越多的,要考慮的問題也越多。數據庫

訂單撮合能夠理解爲訂單買賣,拿這個爲例子進行列舉一個可能會致使數據錯亂的情形。假設如今買賣手機,A用戶是要買手機的,B用戶是賣手機的。A的買入單訂單1,和B的賣出單訂單2,訂單2賣出手機,一臺手機賣1000元。此時A的網上的錢包餘額是1001元,恰好比手機價格高,是能夠成交的。架構

此時記錄用戶錢包錢數數量的是一張數據表。每次花費了錢或者增長了錢,都要更新這個表。併發

當這兩筆訂單進入到系統裏面進行撮合。假設系統的訂單撮合運行流程以下圖所示:高併發

 

 

當判斷條件進行A用戶的錢包餘額判斷的時候,發現 1001 > 1000,結果是經過,此時準備進入「進行記錄更細」步驟。可是,就在這個過程之中的時間差中,A用戶使用了系統的網上提現功能,併成功轉出了10元,剩餘的是1001 - 10 = 991元。可是因爲撮合系統的餘額判斷過程以及經過了,致使下面的交易流程依然能進行,最終A用991元買了B的1000元售價的手機。性能

解決問題

上述的常見問題是一個很簡單的模型,現實的系統中每每是更復雜的。可是它所體現出的問題倒是真實存在的,對於這類問題,有不少解決方案。其中,就能夠考慮使用數據庫的鎖。學習

本文要介紹的是MySQL數據庫共享鎖排他鎖,其它的不做說明或引伸。spa

訂單撮合實例

下面的截圖就是我所重寫好的撮合系統原始的PHP代碼,所使用了表鎖的方式來解決前面的併發讀寫致使數據髒亂的問題。這種方式雖然是解決了問題,可是致使了性能低下的問題。code

 

 

共享鎖 與 排他鎖

前置知識:

  • MySQL 是數據庫,不是數據庫引擎
  • MySQL有兩種經常使用存儲引擎: MyISAMInnoDB
  • MyISAM不支持事務操做,InnoDB支持事務操做
  • MySQL 的鎖分有 行鎖表鎖
  • MyISAM 只有表鎖
  • Innodb 行鎖,表鎖都有
  • 行鎖中有共享鎖排他鎖
  • 共享鎖 簡稱 S鎖,排他鎖簡稱 X鎖

行鎖與表鎖

簡述:索引

  • 行鎖,鎖的是表中對應的行,只限制當前行的讀寫。事務

  • 表鎖,鎖的是整張表,限制的是整張表的數據讀寫。

比較:

  • 行鎖,計算機資源開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,鎖衝突的機率最低,併發度最高,性能高。
  • 表鎖,計算機資源開銷小,加鎖快;不會出現死鎖;鎖定粒度大,鎖衝突的機率最高,併發度最低,性能低。

兩種行鎖的特色

共享鎖

A 對數據 B 加了 共享鎖,A能讀取和修改數據B,C 等其它只能讀取數據B,可是不能修改。直至A釋放了B的鎖。

排他鎖

A 對數據 B 加了 排他鎖,A能讀取和修改數據B,C 等其它不能再對數據B加其它的鎖。直觀體驗是不能修改,不能使用含有加鎖動做的select讀取。

兩種行鎖的加鎖方式

要注意的是:

  • 行鎖的實現SQL語句中必需要有索引的限制條件,例如含有 where id=xxx 這類語句。
  • 行鎖的實現SQL語句沒有索引限制條件會變成表鎖
  • InnoDB引擎 默認的修改數據類SQL語句,update,delete,insert等,都會自動給涉及到的數據加上排他鎖。

共享鎖

  • select 的添加可使用知足格式:select ... where 索引限制 lock in share mode 的語句。例如「select name from lgh_user where id = 1 lock in share model」 此時 id 是索引。

排他鎖

  • 知足格式:select ... where 索引限制 for update 的語句

鎖的釋放

  • 非事務(Transaction) 中,語句執行完畢,便釋放鎖。

  • 行鎖在事務 (Transaction) 中,只有等到當前的事務Transaction 進行了 commit 或 roll back,鎖才能釋放。

操做例子

演示事務 tx 中的例子,文字解析見圖。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

改造代碼片斷

撮合中的全部表鎖替換成了共享鎖,運行其它業務讀取所鎖的行數據,在當前事務的批量操做還沒結束以前,不容許修改。

 


感興趣的能夠本身來個人Java架構羣,能夠獲取免費的學習資料,羣號:855801563 對Java技術,架構技術感興趣的同窗,歡迎加羣,一塊兒學習,相互討論。

相關文章
相關標籤/搜索