[Software Architecture]談資料鎖定(Data Lock)
我們在開發系統時,資料的鎖定是一件很重要的事情,我舉個例子會比較容易了解,我有一張單據長這樣,只有三個欄位,有兩個按鈕,存檔代表的是針對目前的資料進行修改並存檔,而送出是確認此張採購單,送出後這張採購單的內容將被執行,也就是錢的部分就會正式核准了。
下面的劇情是這樣的,某甲跟某乙同時間開了同一張單據,這時候看到採購金額兩者都還是相同的,這時候某甲修改了金額(5500-->550000),並進行存檔,然而這時候某乙畫面上看到的資料還是5500,他覺得沒有錯誤(但資料庫實際存的是550000),就直接按下『送出』,一般的資料處理都是Update by Key,這時候某乙就在不知不覺中送出了一張比他所認知多了100倍的金額,看來他除了受死之外,大概也沒有其他活路了。
上頭是一個沒有進行鎖定的例子,我們常常會被問到對於資料的鎖定是採用什麼樣的做法?一般來說我們粗略的將鎖定分為兩大類:悲觀鎖定與樂觀鎖定。
悲觀鎖定
假設同時修改資料的狀況永遠存在,因此當資料被操作時就應該被鎖定,直到解除鎖定後才能被下一個交易所使用,例如以資料庫的鎖定機制,當某甲修改單據201006120001時,就將這筆資料鎖住,當某乙也想修改這筆資料時,資料庫就直接告知他這筆資料目前由其他人鎖定,他不能使用,請稍後再試,這樣子某乙就清楚知道這筆資料到時可能有異動,應該要關注。
悲觀鎖定的好處就是資料正確性非常的高,但相對的問題也不少,如果在鎖定過程中系統掛了,或者發生exception後沒有將鎖定解除,都會讓資料庫中存在一大堆不在使用中但被鎖定的的資料,系統寫不好的話就要定時去處理這些被lock的資料了。
樂觀鎖定
假設同時修改資料的問題是偶發或者根本不會發生,因此不會去使用悲觀鎖定的處理方式,而改用其他叫溫和的處理方法,例如使用一個Flag或者Token來表示目前資料的狀態,如下圖,當某甲跟某乙處理同一筆資料時,兩個人都會拿到一個Flag這時兩人的Flag是相同的,當某甲進行存檔後,Flag也同時被更新為2,代表資料被異動過了,在某乙要Update資料時,會先去檢查Flag是否與資料庫中相同,如果不同的話,代表資料被修改過,資料就不能被存檔,這種作法也能達到效果。
這種做法沒有實際去將資料鎖定住,因此也不會有需要解除鎖定的需要。
有人說比較大型的系統大多採用悲觀鎖定,比較小型的系統大多用樂觀鎖定,目前看下來似乎是這樣沒錯,兩者比起來我還是比較喜歡悲觀鎖定多一些,因為這樣的架構可由程式來控制,跟環境的關聯就會比較小了,不過我也希望有天能真的讓我遇到非得用悲觀鎖定的系統。
游舒帆 (gipi) 探索原力Co-founder,曾任TutorABC協理與鼎新電腦總監,並曾獲選兩屆微軟最有價值專家 ( MVP ),離開職場後創辦探索原力,致力於協助青少年培養面對未來的能力。認為教育與組織育才其實息息相關,都是在為未來儲備能量,2018年起成立為期一年的專題課程《職涯躍升的關鍵24堂課》,為培養台灣未來的領袖而努力。 |