I’m evaluating PostgreSQL for some personal project.
I was inspirited by it’s Multi-Version Concurrency Control (MVCC)
I simulated a basic need – insert transaction and perform a vendor balance update with many threads at the same time, running the SQL commands like:
INSERT INTO
VendorAccountTransactions (VendorId, BalanceBefore, BalanceAfter)
VALUES (
1,
(SELECT CurrentBalance FROM VendorAccounts WHERE VendorId = 1),
(SELECT CurrentBalance FROM VendorAccounts WHERE VendorId = 1) + 19.99
);
UPDATE VendorAccounts SET CurrentBalance = CurrentBalance + 19.99 WHERE VendorId = 1;
Any Idea how to avoid deadlocks in such common case?
What is is needed – simply insert the transaction description with “balance before” / “balance after” and update the balance.
It will be used in high load application.
How to achieve the right result for this simple business need?
Thank you.
Update:
Maybe there is any other solution to re-design the database to avoid deadlocks or use some other solution to keep the business need solved?
Put the update first and include both statements in a transaction. The update will updlock the vendor row and prevent concurrent transactions from entering the transaction (they will wait until the first tran completed as the updlock is not available).
This will effectively serialize access to a given vendor which will ensure consistency.