In multi-user database environments, multiple operations often need to be executed as a single logical unit. Consider these real-world scenarios:
Fund Transfer: Transfer $500 from Account A to Account B
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 'A';
UPDATE accounts SET balance = balance + 500 WHERE account_id = 'B';
COMMIT;
Problem: What if the system crashes after the first UPDATE but before the second? Account A loses $500, but Account B doesn't receive it!
Order Processing: Customer purchases a product
Challenge: All steps must succeed, or none should be applied!
A transaction is a logical unit of work that contains one or more database operations (read, write, update, delete) that must be executed as a single, indivisible unit.
ACID is the cornerstone of transaction processing, ensuring database reliability and consistency:
Transaction is indivisible - either all operations execute successfully, or none execute at all.
"All or Nothing"
Transaction transforms database from one consistent state to another consistent state.
"Valid State Always"
Concurrent transactions execute independently without interfering with each other.
"Independent Execution"
Once committed, changes are permanent and survive system failures.
"Permanent Changes"
BEGIN TRANSACTION;
-- Step 1: Check Alice's balance
SELECT balance FROM accounts WHERE name = 'Alice'; -- Returns $5000
-- Step 2: Deduct from Alice's account
UPDATE accounts SET balance = balance - 1000 WHERE name = 'Alice';
-- Step 3: Add to Bob's account
UPDATE accounts SET balance = balance + 1000 WHERE name = 'Bob';
COMMIT;
A transaction progresses through various states during its lifecycle:
Figure: Transaction States in DBMS
Source: GeeksforGeeks - Transaction States in DBMS
Normal Flow: Active → Partially Committed → Committed
Error Flow: Active → Failed → Aborted
System Failure: Partially Committed → Failed → Aborted
A schedule defines the chronological order of execution of operations from multiple concurrent transactions.
Transactions execute one after another, completely isolated.
T1: R(A) W(A) R(B) W(B)
T2: R(A) W(A) R(C) W(C)
Timeline: T1 completes entirely, then T2 starts
Pros: Always correct, no conflicts
Cons: Poor performance, low concurrency
Operations from different transactions can interleave.
T1: R(A) W(A) R(B) W(B)
T2: R(A) W(A) R(C) W(C)
Timeline: Operations interleave for better performance
Pros: High performance, better resource utilization
Cons: Risk of conflicts and inconsistencies
Patient Admission Transaction:
ACID Requirement: If any step fails (e.g., no beds available), all steps must be undone.
Flight Booking Transaction:
Challenge: Multiple users booking simultaneously - need proper isolation!
-- Start a transaction
BEGIN TRANSACTION; -- or START TRANSACTION;
-- Your database operations here
INSERT INTO orders (customer_id, product_id, quantity) VALUES (123, 456, 2);
UPDATE inventory SET quantity = quantity - 2 WHERE product_id = 456;
UPDATE customers SET total_orders = total_orders + 1 WHERE id = 123;
-- Commit the transaction (make changes permanent)
COMMIT;
-- Or rollback if something goes wrong
-- ROLLBACK;
Time | Transaction T1 | Transaction T2 | Account Balance
-----|----------------------|----------------------|----------------
1 | READ(balance) = $1000| | $1000
2 | | READ(balance) = $1000| $1000
3 | balance = $1000 + $100| | $1000
4 | | balance = $1000 + $200| $1000
5 | WRITE(balance) = $1100| | $1100
6 | | WRITE(balance) = $1200| $1200
Problem: T1's update ($100) is lost! Final balance should be $1300, not $1200.
Time | Transaction T1 (Withdraw $200) | Transaction T2 (Check Balance) | Account A
-----|--------------------------------|--------------------------------|-----------
1 | BEGIN; | | $1000
2 | UPDATE accounts SET balance = 800 | | $800
| WHERE account_id = 'A'; | |
3 | | BEGIN; | $800
4 | | SELECT balance FROM accounts | $800 (Dirty Read!)
| | WHERE account_id = 'A'; |
5 | ROLLBACK; (Transaction fails) | | $1000
6 | | COMMIT; (Uses invalid data) | $1000
Problem: T2 reads uncommitted data from T1. When T1 rolls back, T2's operations are based on invalid data.
Time | Transaction T1 (Check Balance) | Transaction T2 (Update Balance) | Account A
-----|-------------------------------|-----------------------------------|-----------
1 | BEGIN; | | $1000
2 | SELECT balance FROM accounts | | $1000
| WHERE account_id = 'A'; | |
3 | | BEGIN; | $1000
4 | | UPDATE accounts SET balance = 1200 | $1200
| | WHERE account_id = 'A'; |
5 | | COMMIT; | $1200
6 | SELECT balance FROM accounts | | $1200 (Different from first read!)
| WHERE account_id = 'A'; | |
7 | COMMIT; | | $1200
Problem: T1 reads the same row twice but gets different results because T2 modified it in between.
Time | Transaction T1 (Calculate Total) | Transaction T2 (Add Order) | Orders Table
-----|---------------------------------|-----------------------------|-------------
1 | BEGIN; | | [Order1, Order2]
2 | SELECT COUNT(*) FROM orders | | 2 rows
3 | | BEGIN; | [Order1, Order2]
4 | | INSERT INTO orders VALUES | [Order1, Order2,
| | (Order3, 'Product X', 1); | Order3]
5 | | COMMIT; |
6 | SELECT COUNT(*) FROM orders | | 3 rows (Phantom row!)
7 | COMMIT; | |
Problem: T1 executes the same query twice but gets a different number of rows because T2 inserted a new row that matches T1's query.
Example: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
Task: Create your own transaction scenario and analyze ACID properties
Instructions:
Transaction: Student borrows a book
ACID Analysis:
Lecture 13: Concurrency Control Protocols