Transactions & ACID
Learn how databases guarantee data integrity and consistency, even when things go wrong!
๐ผ What Are Transactions?
A transaction is a sequence of one or more SQL operations that are treated as a single unit of work. Either ALL operations succeed together, or ALL operations fail together - there's no in-between!
๐ฏ Real-Life Analogy: Bank Transfer
Imagine transferring $100 from your savings account to your checking account:
- Step 1: Subtract $100 from savings
- Step 2: Add $100 to checking
What if the computer crashes after Step 1 but before Step 2?
- โ Without a transaction: Your $100 disappears! (Savings reduced, but checking not increased)
- โ With a transaction: If anything fails, BOTH steps are undone. Your money is safe!
Transactions ensure all-or-nothing execution!
Transaction Lifecycle:
BEGIN TRANSACTION;
-- SQL operations here
-- (INSERT, UPDATE, DELETE, etc.)
COMMIT; -- Save all changes permanently
-- OR
BEGIN TRANSACTION;
-- SQL operations here
ROLLBACK; -- Undo all changes
Simple Transaction Example:
BEGIN TRANSACTION;
-- Deduct $100 from Alice's account
UPDATE accounts SET balance = balance - 100 WHERE name = 'Alice';
-- Add $100 to Bob's account
UPDATE accounts SET balance = balance + 100 WHERE name = 'Bob';
COMMIT; -- Both updates are saved together!
If anything goes wrong (power outage, error, etc.), the database automatically rolls back BOTH updates. No partial changes!
๐ Key Transaction Concepts:
- BEGIN TRANSACTION: Starts a transaction (also: BEGIN or START TRANSACTION)
- COMMIT: Saves all changes permanently
- ROLLBACK: Undoes all changes, restores to the state before BEGIN
- Atomic: All-or-nothing - either everything happens or nothing happens
๐ค Why We Need Transactions
Transactions solve real-world problems that happen in multi-step operations!
1. Data Integrity
Prevent partial updates that leave data in an inconsistent state
Example: Money transfer - both debit and credit must happen
2. Error Recovery
If an error occurs, undo all changes automatically
Example: Database crash mid-operation
3. Concurrent Access
Handle multiple users updating the same data simultaneously
Example: Two people booking the last seat on a flight
4. Business Logic
Enforce complex business rules across multiple operations
Example: Order processing with inventory updates
๐ฏ Real-World Scenario: E-Commerce Order
When a customer places an order, multiple things must happen:
BEGIN TRANSACTION;
-- 1. Create the order record
INSERT INTO orders (customer_id, total) VALUES (123, 299.99);
-- 2. Add order items
INSERT INTO order_items (order_id, product_id, quantity) VALUES (5001, 42, 2);
-- 3. Reduce inventory
UPDATE products SET stock = stock - 2 WHERE product_id = 42;
-- 4. Charge the customer
UPDATE customer_balances SET balance = balance - 299.99 WHERE customer_id = 123;
COMMIT; -- All steps complete successfully!
Without a transaction: What if the inventory update fails but the order was already created? Customer is charged but gets nothing!
With a transaction: If ANY step fails, EVERYTHING is rolled back. The customer isn't charged, inventory isn't changed, and the order doesn't exist. Database stays consistent!
Problems Transactions Solve:
- โ Lost Updates: Two users updating the same row at the same time
- โ Partial Failures: Some operations succeed, others fail
- โ Dirty Reads: Reading uncommitted data from another transaction
- โ Inconsistent State: Data violates business rules mid-operation
โ COMMIT and ROLLBACK
Learn to control when changes are saved or discarded!
๐ฏ Real-Life Analogy: Editing a Document
- BEGIN TRANSACTION: Open a Word document and start editing
- Making changes: Type, delete, format - changes are in memory
- COMMIT: Click "Save" - changes written to disk permanently
- ROLLBACK: Click "Close without saving" - all edits discarded
COMMIT - Making Changes Permanent:
Try It: COMMIT Example
๐ What Happened:
- BEGIN TRANSACTION: Started tracking changes
- UPDATEs: Made changes in a temporary state
- COMMIT: Wrote all changes to disk permanently
- Alice's balance: $1000 โ $800
- Bob's balance: $500 โ $700
- Total money in system: $1500 (unchanged, as it should be!)
ROLLBACK - Undoing Changes:
Try It: ROLLBACK Example
Note: In SQLite.js (browser environment), autocommit is on by default. In production databases, transactions give you more control!
๐ When to Use ROLLBACK:
- Error Detection: IF you detect a business rule violation, ROLLBACK
- User Cancellation: User clicks "Cancel" mid-operation
- Validation Failure: Data doesn't pass validation checks
- Dry Run/Testing: Test queries without actually changing data
Real-World Example: ROLLBACK on Error
BEGIN TRANSACTION;
-- Try to withdraw money
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- Check if balance went negative (business rule violation!)
-- In real code, you'd check this programmatically
-- If balance < 0:
ROLLBACK; -- Undo the withdrawal!
-- If balance >= 0:
COMMIT; -- Allow the withdrawal
๐งช Introduction to ACID
ACID is a set of four properties that guarantee reliable database transactions!
๐ฏ What is ACID?
ACID is an acronym for four critical properties that every reliable database transaction must have:
- A - Atomicity
- C - Consistency
- I - Isolation
- D - Durability
These properties work together to ensure your data stays safe, accurate, and reliable - even in the face of errors, crashes, or concurrent users!
Why ACID Matters:
Imagine a database for a hospital, bank, or airline reservation system. A single error could have serious consequences:
- ๐ Hospital: Wrong medication dosage recorded
- ๐ฐ Bank: Money disappearing from accounts
- โ๏ธ Airline: Double-booking the same seat
ACID properties prevent these disasters!
A - Atomicity
All or nothing
Either the entire transaction succeeds, or none of it does
C - Consistency
Rules are never broken
Database always moves from one valid state to another
I - Isolation
Transactions don't interfere
Concurrent transactions happen as if they ran one-at-a-time
D - Durability
Changes are permanent
Once committed, data survives crashes and power failures
Let's explore each property in detail!
โ๏ธ A - Atomicity
Atomicity means transactions are "all-or-nothing" - they either complete fully or have no effect at all.
๐ฏ Real-Life Analogy: Buying a Coffee
When you buy coffee:
- You pay $5
- You receive the coffee
What if the power goes out after you pay but before you get your coffee?
- โ Non-atomic: You lose $5 and get nothing
- โ Atomic: The entire transaction is canceled - you keep your $5, store keeps the coffee
Atomicity ensures you can't have half a transaction!
Example: Atomicity in Action
BEGIN TRANSACTION;
-- Step 1: Deduct from inventory
UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 42;
-- Step 2: Create order
INSERT INTO orders (customer_id, product_id) VALUES (101, 42);
-- Step 3: Charge customer
UPDATE customers SET balance = balance - 99.99 WHERE customer_id = 101;
COMMIT;
With Atomicity:
- โ All 3 steps succeed: COMMIT saves everything
- โ Any step fails: ROLLBACK undoes everything automatically
- โ Database crashes: On restart, transaction is completely undone
Without Atomicity:
- โ Inventory reduced but order not created
- โ Customer charged but no order record
- โ Inconsistent, broken database state
Key Points About Atomicity:
- Think of each transaction as a single, indivisible unit
- The word "atomic" comes from Greek atomos = "uncuttable"
- Partial updates are never visible to other users or after crashes
- Database automatically handles ROLLBACK if anything goes wrong
โ๏ธ C - Consistency
Consistency means the database always moves from one valid state to another valid state, never violating any rules or constraints.
๐ฏ Real-Life Analogy: Chess Game Rules
In chess, certain rules must always be followed:
- Each player has exactly one king
- Pawns can't move backward
- You can't move into check
Consistency means the database enforces rules like constraints, triggers, and business logic - just like a chess app won't let you make illegal moves!
Example: Consistency with Constraints
CREATE TABLE accounts (
account_id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
balance REAL CHECK(balance >= 0) -- Constraint: balance can't be negative
);
BEGIN TRANSACTION;
-- Valid transaction (respects constraint)
UPDATE accounts SET balance = balance - 50 WHERE account_id = 1;
-- If balance was $100, it's now $50 โ
Still valid (>= 0)
COMMIT; -- Success!
BEGIN TRANSACTION;
-- Invalid transaction (violates constraint)
UPDATE accounts SET balance = balance - 200 WHERE account_id = 1;
-- If balance was $50, this would make it -$150 โ Violates constraint!
-- Database automatically ROLLBACK this transaction!
-- Consistency preserved!
What Consistency Enforces:
- Constraints: CHECK, NOT NULL, UNIQUE, FOREIGN KEY
- Data types: Can't insert text into an INTEGER column
- Triggers: Automatic actions that enforce business rules
- Referential integrity: Foreign keys must reference existing rows
๐ Real-World Example: Money Transfer
Business Rule: Total money in the system must stay constant
Before transaction:
- Alice: $1000
- Bob: $500
- Total: $1500
After transaction:
- Alice: $800 (sent $200)
- Bob: $700 (received $200)
- Total: $1500 โ (same as before - consistent!)
If only one UPDATE happened, the total would be $1300 or $1700 - violating consistency!
Valid State
Before Transaction
All constraints satisfied โ
โฌ๏ธ Transaction Executes
May temporarily violate rules internally
(but never visible externally!)
Valid State
After Transaction
All constraints satisfied โ
๐ I - Isolation
Isolation means concurrent transactions don't interfere with each other - they execute as if they're the only transaction running.
๐ฏ Real-Life Analogy: ATM Withdrawals
Imagine you and your spouse both try to withdraw money from the same account at the same time:
- Account balance: $500
- You withdraw: $400 at ATM #1
- Spouse withdraws: $300 at ATM #2 (at the same moment!)
Without isolation:
- Both ATMs read balance: $500
- ATM #1 deducts $400, writes $100
- ATM #2 deducts $300, writes $200
- Final balance: $200 (but you withdrew $700 total - $200 disappeared!)
With isolation:
- ATM #1 locks the account, reads $500
- ATM #1 deducts $400, writes $100, unlocks
- ATM #2 locks the account, reads $100
- ATM #2 rejects withdrawal (insufficient funds)
- Final balance: $100 โ Correct!
Isolation Prevents:
- Dirty Reads: Reading uncommitted changes from another transaction
- Non-Repeatable Reads: Reading the same data twice in a transaction but getting different values
- Phantom Reads: New rows appearing between two reads in the same transaction
- Lost Updates: Two transactions updating the same row, one overwriting the other
Example: Isolation in Action
-- Transaction 1 (running concurrently)
BEGIN TRANSACTION;
UPDATE products SET stock = stock - 1 WHERE product_id = 42;
-- Transaction is active but NOT yet committed...
-- Transaction 2 (running at the same time)
BEGIN TRANSACTION;
SELECT stock FROM products WHERE product_id = 42;
-- What value does it see?
-- With ISOLATION: Sees the OLD value (before Transaction 1's update)
-- Transaction 2 doesn't see uncommitted changes!
-- Transaction 1 completes
COMMIT; -- Now the change is visible to others
-- Transaction 2 continues
SELECT stock FROM products WHERE product_id = 42;
-- Still sees the OLD value (reads are consistent within a transaction)
COMMIT;
๐ How Isolation Works (Simplified):
Databases use locks or versioning to provide isolation:
1. Locking:
- When you read/write a row, database puts a "lock" on it
- Other transactions must wait for the lock to be released
- Prevents two transactions from modifying the same data simultaneously
2. Multi-Version Concurrency Control (MVCC):
- Each transaction sees a "snapshot" of the database from when it started
- Reads don't block writes, writes don't block reads
- More efficient but more complex to implement
Isolation Levels (Advanced):
Different levels of isolation offer different trade-offs between safety and performance:
- READ UNCOMMITTED: Weakest, fastest (allows dirty reads)
- READ COMMITTED: Most common default
- REPEATABLE READ: Stronger isolation
- SERIALIZABLE: Strongest, slowest (transactions run as if sequential)
SQLite uses SERIALIZABLE by default!
๐พ D - Durability
Durability means once a transaction is committed, the changes are permanent - even if the system crashes immediately after!
๐ฏ Real-Life Analogy: Saving a Document
When you click "Save" in a word processor:
- Before save: Your work is in RAM (volatile memory)
- After save: Your work is on the hard drive (permanent storage)
- Power outage 1 second after save: Your work is still safe! โ
Durability means COMMIT works like that "Save" button - once it's done, your data is safe from crashes!
Example: Durability Guarantees
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance + 1000 WHERE account_id = 123;
COMMIT; -- โ
Data is written to disk!
-- Even if these disasters happen 1 millisecond after COMMIT:
-- โ Power failure
-- โ System crash
-- โ Database process killed
-- When the database restarts:
-- โ
The $1000 credit is still there!
-- โ
Transaction is NOT lost!
๐ How Durability Works:
Databases use several techniques to ensure durability:
1. Write-Ahead Logging (WAL):
- Before making changes, database writes them to a log file on disk
- Log is written sequentially (fast!)
- If crash happens, database replays the log on restart
- Used by SQLite, PostgreSQL, MySQL
2. Force Writes to Disk:
- COMMIT doesn't return until data is physically written to disk
- Uses
fsync()system call to force OS to flush buffers - Ensures data survives power failures
3. Redundancy:
- Write to multiple disks (RAID)
- Replicate to backup servers
- Even if one disk fails, data is safe
What Durability Protects Against:
- ๐ฅ Power failures
- ๐ฅ System crashes
- ๐ฅ Hardware failures
- ๐ฅ Operating system crashes
- ๐ฅ Database process crashes
Once COMMIT returns, your data is SAFE!
Before COMMIT
Changes in memory
โ Not durable (lost on crash)
During COMMIT
Writing to disk
โณ Becoming durable...
After COMMIT
Safely on disk
โ Durable (survives crashes!)
Important Note:
Durability is why databases are sometimes slower than just storing data in memory. The trade-off is worth it - you get guaranteed safety even in disasters!
๐ผ Practical Use Cases
Let's see how transactions are used in real-world applications!
1. Banking
Money transfers, deposits, withdrawals
Critical: Can't lose money!
2. E-Commerce
Order processing, inventory updates
Critical: Don't charge without shipping!
3. Social Media
Post creation, like counts, follower updates
Important: Keep counts accurate
4. Booking Systems
Hotel, flight, concert ticket reservations
Critical: No double-booking!
5. Healthcare
Patient records, medication logs
Critical: Accuracy is life-or-death
6. Gaming
Inventory, points, achievements
Important: Fair gameplay
Real-World Example: Hotel Booking
BEGIN TRANSACTION;
-- Check if room is available
SELECT available FROM rooms WHERE room_id = 101;
-- Returns: available = 1 (YES)
-- Reserve the room
UPDATE rooms SET available = 0 WHERE room_id = 101;
-- Create booking record
INSERT INTO bookings (customer_id, room_id, check_in, check_out)
VALUES (456, 101, '2024-03-15', '2024-03-20');
-- Charge the customer
UPDATE customers SET balance = balance - 500 WHERE customer_id = 456;
COMMIT; -- All or nothing!
Why transaction is essential:
- โ If credit card declines, room stays available (ROLLBACK)
- โ If system crashes, no partial booking (ATOMICITY)
- โ Two people can't book the same room (ISOLATION)
- โ Once booked, reservation survives crashes (DURABILITY)
๐ Transaction Best Practices:
- Keep transactions short: Long transactions lock resources
- Use transactions for multi-step operations: Anything that must happen together
- Don't mix user input with transactions: Don't wait for user during a transaction
- Handle errors: Always have error handling that calls ROLLBACK
- Test failure scenarios: Make sure ROLLBACK works correctly
Practice Exercises
Part 1: Guided Exercises
Guided Exercise 1: Safe Money Transfer
Task: Create a transaction that safely transfers $50 from Account 1 to Account 2. Both updates must succeed or both must fail.
Part 2: Independent Practice
Challenge 1: E-Commerce Order Processing
Difficulty: Medium
Task: Create a transaction that processes an order - reduce inventory by 2 units for product_id 1, and create an order record. Use BEGIN TRANSACTION and COMMIT.
๐ Knowledge Check Quiz
1. What does COMMIT do in a transaction?
2. Which ACID property ensures "all or nothing" execution?
3. Which property ensures committed data survives crashes?