2018-04-30

RDBMS 的 lock 更新前置計算或然率

首先,自己一般的寫法

SELECT ... FROM items WHERE id = 123
#前置檢查 status 或其他欄位,可免除 lock 成本,甚至可以快取還有額外運算
SELECT ... FROM items WHERE id = 123 FOR UPDATE
# row base lock 開始
# a = a + 1
# 很慢的 function 要處理,處理完後會塞回原值或其他欄位
UPDATE items SET ... WHERE id = 123


但其實可以改成

SELECT ... FROM items WHERE id = 123
# 前置檢查 status 或其他欄位,可免除 lock 成本,甚至可以快取還有額外運算
# ori_a = a
# new_a = ori_a + 1
# 很慢的 function 要處理,並暫存於其他欄位
SELECT ... FROM items WHERE id = 123 FOR UPDATE
# row base lock 開始
# if ori_a == a #額外判斷成本
#   a = new_a
#   直接把暫存欄位也直接塞入,免除計算
#   #賺到的部分
# else
#   重新處理:很慢的 function 要處理,處理完後會塞回原值或其他欄位
#   #虧的部分
# end
UPDATE items SET ... WHERE id = 123


原因是 lock 有其餘 service 的交互影響,這樣做就可以把 lock 在一定機率內最小化,且命中率 50% 時應該全都是賺的,而虧的時候只賠了一個 if 的判斷(或多個?)重新計算則幾乎等於原本成本 ... 原本 DB 的 lock 成本要等待所有單一主機流水式的算完,而省略成碰撞後才需要之類的

anyway 這思維還滿酷炫的哈哈,或許可以考慮實作?(主要節省「很慢的 function 要處理」可以盡量不在 lock 內完成 ......)且還要測試 if 的成本是否高於該成本才是 ......

沒有留言:

張貼留言