Introduction
ACID is a set of properties that guarantee reliable processing of database transactions. These properties ensure data integrity even in the face of errors, power failures, and other mishaps.ACID compliance is a hallmark of traditional relational databases and is critical for applications where data correctness is paramount.
- Atomicity
- Consistency
- Isolation
- Durability
What is a Transaction?
Before diving into ACID, let’s understand transactions: A transaction is a sequence of one or more database operations (reads/writes) treated as a single logical unit of work.The Four ACID Properties
Atomicity: All or Nothing
Definition: The writes in a transaction are executed all at once and cannot be broken into smaller parts. If there are faults when executing the transaction, the writes in the transaction are rolled back.Atomicity means 'all or nothing'
Either all operations in a transaction succeed, or none of them do. There’s no partial success.
How Atomicity Works
Successful transaction:Without atomicity, the first operation might succeed while the second fails, leaving the system in an inconsistent state (money disappeared!).
Implementation Mechanisms
Databases achieve atomicity through: Write-Ahead Logging (WAL):- Store “before” images of data
- If transaction fails, restore original values
- After successful commit, discard rollback data
Real-World Example
E-commerce order placement:- Order is not created
- Inventory is not decremented
- System remains consistent
Consistency: Preserving Database Invariants
Definition: Any data written by a transaction must be valid according to all defined rules and maintain the database in a good state.Unlike “consistency” in the CAP theorem (which means every read receives the most recent write), ACID consistency means preserving database invariants and constraints.
What are Invariants?
Invariants are rules that must always be true: Examples:- Foreign key constraints (orders must reference valid customers)
- Unique constraints (email addresses must be unique)
- Check constraints (age must be >= 0)
- Business rules (account balance cannot be negative)
- Data types (age must be an integer)
How Consistency Works
Before transaction:The total amount of money in the system remains constant—a critical business invariant.
Constraint Enforcement
Databases enforce consistency through: Foreign Key Constraints:Isolation: Concurrent Transactions Don’t Interfere
Definition: When there are concurrent writes from two different transactions, the two transactions are isolated from each other.The most strict isolation is serializability, where each transaction acts like it is the only transaction running in the database. However, this is hard to implement in reality, so we often adopt looser isolation levels.
Why Isolation Matters
Without isolation, concurrent transactions can interfere:Isolation Levels
SQL defines four isolation levels, trading off consistency for performance:Read Uncommitted (Lowest)
Read Uncommitted (Lowest)
Definition: Transactions can read data modified by other uncommitted transactions.Problems:Use cases: Rarely used; perhaps for approximate analytics where accuracy isn’t critical.
- Dirty Reads: Reading uncommitted changes that may be rolled back
Read Committed
Read Committed
Definition: Transactions can only read data that has been committed.Problems Solved:Use cases: Default for many databases (PostgreSQL, Oracle).
- ✓ No dirty reads
- Non-Repeatable Reads: Reading same row twice gives different results
Repeatable Read
Repeatable Read
Definition: Data read during the transaction stays the same as when the transaction started.Problems Solved:Use cases: MySQL/InnoDB default; good balance for most applications.
- ✓ No dirty reads
- ✓ No non-repeatable reads
- Phantom Reads: New rows appearing in range queries
Serializable (Highest)
Serializable (Highest)
Definition: Transactions execute as if they ran one at a time, in sequence.Problems Solved:
- ✓ No dirty reads
- ✓ No non-repeatable reads
- ✓ No phantom reads
- Significantly lower concurrency
- Higher latency
- More lock contention
Implementation: MVCC
Most modern databases use MVCC (Multi-Version Concurrency Control) to implement isolation efficiently.
How MVCC works:
Each row has hidden metadata:
transaction_id: Which transaction created/modified this versionroll_pointer: Pointer to previous version of the row
Transaction A Modifies Balance
New row: Balance = 200 (transaction_id = 201, uncommitted)
Roll pointer → old row (Balance = 100)
Transaction B Reads Balance
Sees transaction_id = 201 is uncommitted
Follows roll_pointer → reads Balance = 100
MVCC allows readers and writers to avoid blocking each other, dramatically improving concurrency compared to traditional locking.
Durability: Surviving Failures
Definition: Data is persisted after a transaction is committed, even in case of system failure. In a distributed system, this means the data is replicated to some other nodes.Durability guarantees permanence
Once a transaction is committed, the changes are permanent—even if the server crashes immediately after.
Why Durability Matters
Without durability:Implementation Mechanisms
Write-Ahead Logging (WAL):The key insight: Writing sequentially to a log file is much faster than random writes to data files. WAL improves both durability and performance.
- Periodically flush dirty pages to disk
- Allows truncating old log files
- Reduces recovery time
Durability vs Performance
Strict durability (fsync after every commit) can be slow. Some systems offer options: PostgreSQL:ACID in Practice
Example: Bank Transfer
Let’s see all four ACID properties in action:Atomicity: Both updates happen or neither does
Consistency: Balance constraint is enforced; total money unchanged
Isolation: Other transactions see either old or new state, not intermediate
Durability: After commit, transfer survives crashes
ACID vs BASE
NoSQL databases often follow BASE instead of ACID: BASE stands for:- Basically Available
- Soft state
- Eventual consistency
| Aspect | ACID | BASE |
|---|---|---|
| Consistency | Strong, immediate | Eventual |
| Availability | May sacrifice for consistency | Prioritized |
| Complexity | Database handles | Application handles |
| Use Case | Financial, critical data | Social media, caching |
| Examples | PostgreSQL, MySQL | Cassandra, DynamoDB |
ACID and BASE represent different trade-offs in the CAP theorem spectrum. Neither is universally better—choose based on your requirements.
When ACID is Critical
Use ACID-compliant databases when:Financial transactions (banking, payments)
Inventory management (can’t oversell)
Healthcare records (accuracy is critical)
Booking systems (hotels, flights)
Order processing (e-commerce)
Any system where data correctness is paramount
When to Consider Non-ACID
You might relax ACID requirements for:Social media feeds (eventual consistency is fine)
Analytics and reporting (approximate is acceptable)
Caching layers (stale data is tolerable)
High-throughput logging
IoT sensor data
Common Pitfalls
Best Practices
Keep Transactions Short
Minimize the time transactions hold locks. Do expensive operations outside transactions.
Choose the Right Isolation Level
Don’t default to serializable unless necessary. Most apps work fine with read committed or repeatable read.
Conclusion
ACID properties are fundamental to reliable data storage:- Atomicity ensures all-or-nothing execution
- Consistency preserves database invariants
- Isolation prevents concurrent transaction interference
- Durability guarantees committed changes survive failures
Next Steps
CAP Theorem
Understand trade-offs in distributed databases
Database Isolation
Deep dive into isolation levels and MVCC
Choosing a Database
Select the right database for your needs
Database Replication
Learn how replication affects ACID properties