記一次髒讀導致的數據錯誤

記錄一次修改表中的金額可能導致數據庫髒讀的情況

場景是:一張訂單明細表,一張訂單總金額表。目前訂單隻有個產品。所以訂單總金額表裏記錄只有一條數據。當訂單明細表增加時,同事更新總金額表。接口調用是通過MQ消息推送。

原來的開發邏輯,明細表數據入庫之後。查詢總金額表是否有數據,沒有就進行新增,有就進行更新。

明細表數據入庫這塊是沒有任何問題的,這塊不用管。主要是更新總金額表的地方存在潛在的髒讀問題。

第一次的具體實現:數據入庫後,查詢總金額表,返回對象totalAmount,判斷totalAmount是否爲null,如果爲null,則新增一條記錄,這個分支麼有任何問題的不用管。如果不爲null,說明totalAmount記錄已經存在了,需要更新他的金額字段。更新的語句也是傳的totalAmount這個對象的,所以我重新給totalAmount的屬性amout賦值了,在原來的amount上加上本次傳過來的amount。然後調用更新方法,傳對象totalAmount就可以了。

這個是原先的實現方法,感覺一切都那麼的自然,沒有任何問題的。但是恰恰就是這裏是有問題滴。假設上面的場景MQ推送了兩條數據過來,第一條數據執行到一半是還沒有執行到數據庫時,第二條數據MQ也推送過來了。此時查詢庫裏是否有訂單總金額時和第一條查詢時返回的結果是一樣的。然後接着第一條更新數據庫執行完畢。第二條數據給amount賦值時,就是把前面第一條剛剛更新的數據就覆蓋了。導致該條數據在明細表添加了,卻在總金額表裏沒有累加到。

修改之後的實現方法,前面都是一樣的,只是在累加總金額時做了調整。原來是在代碼裏計算添加總金額,然後重新set到對象totalAmount中,現在我們不在在代碼計算,而是直接在sql語句上計算,更新訂單總金額表的總金額是 set amount=amount+本次明細的金額。這樣修改在庫裏更新的時候就不會出現上面說那種情況了。當然這個髒讀也只是偶發,可能測試數據少,很難發現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章