大促場景下庫存更新 SQL 優化
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
本篇文章討論的大促場景,指雙 11、618 期間,系統的行為是要盡可能多地賣出商品,盡可能多地收訂單,又不能超過庫存。在這種高并發、大流量場景下,整個系統的瓶頸點必然在數據庫上,本篇文章就庫存更新這一場景下討論如何優化事務 SQL。 在文章開始之前,我們做出如下約定:
兩種事務代碼,誰更優?我們售賣一件商品的流程是什么呢?首先要先查詢一下商品是否還有庫存?如果有庫存,我們就創建一個訂單,商品庫存減去 1(為了方便分析,我們只討論這種比較簡單的情況)。并且,我們還知道上述操作應當封裝在一個事務中,如果其中一步失敗了,就應當進行回滾。 好的,基于上述的描述,我們有如下兩種事務代碼的編寫方式。 寫法 1
寫法 2
兩種寫法的區別就是一個先插入再更新,另一個是先更新再插入。仔細想一想,哪一種寫法更優,從 TPS 的角度來考慮一下。 公布答案第一種寫法更優(先插入再更新),TPS 比第二種高得多。 為什么呢?首先,我們要知道上面的每一條數據庫操作語句,包括最后的 commit 或者 rollback 都要由業務服務向數據庫發送網絡請求,并且要等待數據庫返回語句執行結果(同步)。 還記得我們在最開始做的約定嗎?在計算兩種寫法的 TPS 之前,我再給上面的代碼加些注釋,讓你更容易理解。
寫法 1 注釋版
寫法 2 注釋版
計算兩種寫法的 TPS在計算之前,我們還要再回顧一下關于數據庫中鎖的基礎知識。 1、update 命令會施加一個 X 型記錄鎖,X 型記錄鎖是寫寫互斥的。如果 A 事務對 goods 表中 id = 1 的記錄行加了記錄鎖,B 事務想要對這行記錄加記錄鎖就會被阻塞。 2、insert 命令會施加一個插入意向鎖,但插入意向鎖是互相兼容的。如果 A 事務向 order 表 insert 一條記錄,不會影響 B 事務 insert 一條記錄。 3、記錄鎖要等到事務提交之后才會釋放! 好的,基于最開始的約定,代碼的注釋,以及基礎知識,我們可以來計算了。 寫法 1 的 TPScommit 網絡請求 1 次,commit 語句執行一次,我們在這里可以先忽略語句執行耗時。
寫法 2 的 TPSinsert、commit 共兩次網絡請求,兩條語句執行,我們也忽略語句執行耗時。
我們可以看到兩者的 TPS 差了 2 倍。試想一下,如果事務中有更多的數據庫操作,寫法 2 的 TPS 會進一步降低。 繼續優化寫法 1 是否還有進一步優化的空間呢?update 執行成功與否數據庫是知道的,如果省去 commit 這個網絡請求,那么 TPS 是多少呢?
當然,這個優化就要依靠你們公司的 DBA 了。 總結當我們在編寫一個事務的時候,加行鎖的操作應在不影響業務的情況下,盡可能地靠近 commit 語句,這樣單行記錄的行鎖時間才會更短,TPS 會更高。 ?轉自https://juejin.cn/post/7266302333634215976 該文章在 2025/3/7 10:26:43 編輯過 |
關鍵字查詢
相關文章
正在查詢... |