並行處理下發生的衝突
取得未讀信件數量
SELECT COUNT(*)
FROM emails
WHERE recipient_id = 2
AND unread_flag = true
去正規化以提升效率
-- INSERT INTO emails ..
-- 新增完之後,再增加未讀信件的數量
UPDATE mailboxes
SET unread = unread + 1
WHERE recipient_id = 2;
使用者2 明明有新郵件,卻顯示 0
同時對單一值加一
我們需要哪些東西處理競賽狀況?
避免別的請求看得到你未完成的狀態。
讓你可以放心捨棄請求
我盡可能把事做好,但做過的事不能重來
為什麼 ORM(Object-Relational Mapping)的框架通常不預設重做?
dirty-read
dirty-write
加鎖,避免同時寫入
等完成交易,再合併
no read-skew
讀取偏斜(read-skew)
賦予每個交易增量編號
索引指向的地方涵蓋多版本的資料
write-skew
情境:晚上醫院值班。
寫入偏斜的變形
BEGIN TRANSACTION;
SELECT COUNT(*) FROM bookings
WHERE room_id = 123
AND end_time > '2000-01-01 12:00'
AND start_time < '2000-01-01 13:00';
INSERT INTO bookings
(room_id, start_time, end_time, user_id)
VALUES (123, '2000-01-01 12:00', '2000-01-01 13:00', 666);
COMMIT;
SELECT COUNT(*)
FROM users
WHERE user_account = 'new_user'
INSERT INTO users
(user_id, user_account)
VALUES (123, 'new_user');
最強的隔離性
VoltDB, H-Store, Redis, Datomic
讀時不能寫、寫時不能讀
Serializable Snapshot Isolation (SSI)
偵測衝突,而非阻止並行
同時編輯維基百科,要退回其中一個還是整合兩個編輯?