Imagine multiple people trying to update the same bank account balance at the same time. What problem does concurrency control help to prevent?
Think about what happens if two people try to change the same number at once without coordination.
Concurrency control ensures that when multiple users try to change the same data at the same time, their changes do not conflict or cause incorrect results. This prevents data loss or corruption.
Two transactions run concurrently on a PostgreSQL database with a table accounts having a row with id=1 and balance=100.
Transaction 1: BEGIN; UPDATE accounts SET balance = balance + 50 WHERE id = 1; COMMIT;
Transaction 2: BEGIN; UPDATE accounts SET balance = balance - 30 WHERE id = 1; COMMIT;
If both transactions run at the same time without concurrency control, what could be the final balance?
SELECT balance FROM accounts WHERE id = 1;
Consider what happens if one update overwrites the other without seeing it.
If concurrency control is missing, one update might overwrite the other, causing lost updates. The correct final balance after both updates should be 120.
In PostgreSQL, which statement locks a specific row in the accounts table to prevent other transactions from modifying it until the current transaction finishes?
Look for the standard SQL syntax that locks rows for update.
The FOR UPDATE clause locks the selected rows so other transactions cannot modify them until the lock is released.
Deadlocks happen when two transactions wait for each otherβs locks. Which practice helps reduce deadlocks in a PostgreSQL database?
Think about how consistent ordering can prevent circular waits.
Accessing tables and rows in the same order prevents circular waiting, which is the main cause of deadlocks.
Two concurrent transactions run these commands:
-- Transaction 1 BEGIN; SELECT balance FROM accounts WHERE id = 1; UPDATE accounts SET balance = balance + 100 WHERE id = 1; COMMIT; -- Transaction 2 BEGIN; SELECT balance FROM accounts WHERE id = 1; UPDATE accounts SET balance = balance - 50 WHERE id = 1; COMMIT;
Both use SERIALIZABLE isolation level. Why might one transaction fail with a serialization error?
Think about how PostgreSQL ensures transactions appear as if they ran one after another.
Under SERIALIZABLE isolation, PostgreSQL detects when concurrent transactions could cause inconsistent results and aborts one with a serialization failure to keep data correct.