Digital Wallet System
Balance ko ek simple column mein rakhna aur update karna sabse common galti hai. Sahi approach hai balance ko LEDGER ENTRIES ka jod maanna — current balance ek derived value hai, source of truth nahi. Performance ke liye periodic SNAPSHOT rakho (jaise har raat ka closing balance) taaki poora ledger baar-baar na padhna pade.
Concurrency yahan sabse critical hai. Ek hi wallet par do parallel debits balance ko negative kar sakte hain. Solution: per-wallet OPTIMISTIC LOCKING (version column) ya conditional update ("WHERE balance >= amount"). High-traffic wallets ke liye single-writer approach — us wallet ke saare transactions ek hi partition/queue se serialize karke.
-- Atomic debit — negative balance yahin rukta hai
UPDATE wallets
SET balance = balance - :amt, version = version + 1
WHERE wallet_id = :id
AND balance >= :amt
AND version = :expectedVersion;
-- affected rows 0 => ya paise kam the, ya koi aur pehle update kar gaya- Balance ledger ka derived jod hai; snapshots se read fast rakho
- Conditional/optimistic update se negative balance rukta hai
- Daily reconciliation — ledger sum vs stored balance
Ek popular merchant ka wallet (jaise bada e-commerce seller) ek second mein hazaaron transactions le sakta hai. Us ek row par lock lagane se poora system atak jaata hai — ye "hot key" ya "hot partition" problem hai.
Solution hai BALANCE SHARDING: ek logical wallet ko N sub-balances mein baanto. Credit random sub-balance mein jaaye, debit ke liye kisi ek se lo (kam pade to doosre se). Total balance sab sub-balances ka jod hai. Isse contention N guna kam ho jaata hai.
// Ek wallet, 10 sub-balances => contention 10x kam
wallet:merchant_123:shard_0 ... shard_9
credit → random shard par
debit → ek shard try karo, kam pade to agla
balance → SUM(saare shards)Har wallet operation ke saath client ek unique request id bhejta hai. Server usko result ke saath store karta hai. Retry par wahi stored result wapas jaata hai — dobara debit nahi hota.
Ek important detail: idempotency record ki RETENTION. Usko hamesha nahi rakh sakte (storage badhta jaayega), par bahut jaldi delete bhi nahi kar sakte (late retry double charge kar dega). Practically 24-48 ghante rakhna standard hai.