.NET---Exceptionless 輕量級的分散式日誌管理平臺
阿新 • • 發佈:2021-07-20
如一個金融系統,當某個操作員讀取使用者的資料,並在讀出的使用者資料的基礎上進行修改時(如更改使用者帳戶餘額),如果採用悲觀鎖機制,也就意味著整個操作過 程中(從操作員讀出資料、開始修改直至提交修改結果的全過程,甚至還包括操作 員中途去煮咖啡的時間),資料庫記錄始終處於加鎖狀態,可以想見,如果面對幾百上千個併發,這樣的情況將導致怎樣的後果。
樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於資料版本 ( version )記錄機制實現。何謂資料版本?即為資料增加一個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加一個 “version” 欄位來實現。
讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。同時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號等於資料庫表當前版本號,則予以更新,否則認為是過期資料。
對於上面修改使用者帳戶資訊的例子而言,假設資料庫中帳戶資訊表中有一個 version 欄位,當前值為 1 ;而當前帳戶餘額欄位( balance )為 $100 。
1 操作員 A 此時將其讀出( version=1 ),並從其帳戶餘額中扣除 $50( $100-$50 )。
2 在操作員 A 操作的過程中,操作員B 也讀入此使用者資訊( version=1 ),並從其帳戶餘額中扣除 $20 ( $100-$20 )。
3 操作員 A 完成了修改工作,將 version=1 的資料連同帳戶扣除後餘額( balance=$50 ),提交至資料庫更新,此時由於提交資料版本等於資料庫記錄當前版本,資料被更新,同時資料庫記錄 version 更新為 2(set version=version+1 where version=1) 。
4 操作員 B 完成了資料錄入操作,也將 version=1 的資料試圖向資料庫提交( balance=$80 ),但此時比對資料庫記錄版本時發現,操作員 B 提交的資料版本號為 1 ,資料庫記錄當前版本也為 2 ,不滿足 “ 提交版本必須等於記錄當前版本才能執行更新 “ 的樂觀鎖策略,因此,操作員 B 的提交被駁回。
這樣,就避免了操作員 B 用基於 version=1 的舊 資料修改的結果覆蓋操作員A 的操作結果的可能。