Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • About
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

👥10,106visitors

Built for engineers who want to go deep.


← Database Fundamentals

Database Foundations

  • ACID Properties
  • Indexes & Query Performance
  • Transactions & Isolation Levels
  • Practical SQL & JDBC for Interviews
  • Query Execution Plans
  • Connection Pooling

Database Design

  • Normalization (1NF–3NF)
  • SQL Joins & Set Operations
  • Window Functions
  • The N+1 Query Problem
  • Sharding vs Partitioning vs Replication
  • Denormalization & Schema Trade-offs
  • Database Scaling Decision Framework
Chaturmind
← Database Fundamentals

Database Foundations

  • ACID Properties
  • Indexes & Query Performance
  • Transactions & Isolation Levels
  • Practical SQL & JDBC for Interviews
  • Query Execution Plans
  • Connection Pooling

Database Design

  • Normalization (1NF–3NF)
  • SQL Joins & Set Operations
  • Window Functions
  • The N+1 Query Problem
  • Sharding vs Partitioning vs Replication
  • Denormalization & Schema Trade-offs
  • Database Scaling Decision Framework
HomeLearnDatabasesDatabase FundamentalsDatabase Foundations
✓ FreeIntermediate· 6 min read

ACID Properties

Atomicity, Consistency, Isolation, Durability — why they matter and how databases enforce them.

Published September 21, 2026


ACID Properties

A transaction groups several database operations into a single logical unit of work. Transferring ₹500 from Asha to Vikram means debiting one account, crediting another, and recording the transfer. If the system crashes, or another transfer runs at the same time, we need guarantees that the data still makes sense. ACID names those guarantees:

  • Atomicity
  • Consistency
  • Isolation
  • Durability
BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE id = 'asha'  AND balance >= 500;
-- the application checks that exactly 1 row was updated; if not → ROLLBACK
UPDATE accounts SET balance = balance + 500 WHERE id = 'vikram';
INSERT INTO transfers (from_id, to_id, amount) VALUES ('asha', 'vikram', 500);
COMMIT;

Advertisement

Atomicity: all or nothing

Either every operation in the transaction takes effect, or none do. If the credit fails, or the server crashes after the debit, the debit is undone. There's never a state where money left one account and arrived nowhere.

How databases achieve it:

  • Write-ahead logging (WAL): changes are recorded in a log before being applied. After a crash, recovery redoes committed transactions and undoes uncommitted ones.
  • Undo information (undo logs in InnoDB, old row versions in PostgreSQL) lets an explicit ROLLBACK restore the previous state.

Atomicity is about failure, not concurrency: "the transaction happened completely or not at all."

Consistency: rules are never broken

A transaction moves the database from one valid state to another. Valid means every rule holds: constraints (NOT NULL, UNIQUE, foreign keys, CHECK (balance >= 0)), plus the application's own invariants (the total money across accounts is unchanged by a transfer).

The database enforces the declared constraints, and rejects a transaction that would violate them. But invariants that only exist in application logic are the application's responsibility. Consistency is therefore partly a property of the database, and partly of correctly written transactions.

Don't confuse this "C" with the "C" in the CAP theorem, which means all replicas agreeing (linearizability). See CAP Theorem.

Isolation: concurrent transactions don't corrupt each other

Many transactions run simultaneously. Isolation controls how much they can see of each other's uncommitted or in-progress work. Ideally, each would behave as if it ran alone (serializable), but full isolation costs performance, so databases offer weaker levels.

The anomalies that weaker levels allow:

AnomalyWhat happens
Dirty readReading another transaction's uncommitted change, which may later be rolled back
Non-repeatable readReading the same row twice in one transaction, and getting different values because another transaction committed in between
Phantom readRe-running a query and getting different rows (new matching rows were inserted)
Lost updateTwo transactions read, modify and write the same value, and one overwrites the other
Write skewTwo transactions each check a condition, then write different rows, together breaking the rule. Example: two doctors each see "another doctor is on call" and both go off call
LevelPreventsTypical default in
Read UncommittedAlmost nothingRarely used
Read CommittedDirty readsPostgreSQL, Oracle, SQL Server
Repeatable Read+ non-repeatable reads (and phantoms in PostgreSQL and InnoDB for consistent reads)MySQL InnoDB
SerializableAll anomalies, including write skewOpt-in

Implementations differ:

  • MVCC (multi-version concurrency control, used by PostgreSQL, InnoDB and Oracle) gives each transaction a snapshot, so readers don't block writers.
  • Locks (row locks, SELECT … FOR UPDATE) serialize conflicting writes.
  • PostgreSQL's Serializable uses SSI, which detects dangerous patterns and aborts one transaction. The application must be prepared to retry.

The details and practical choices are in Transactions & Isolation Levels.

Durability: committed means saved

Once COMMIT returns successfully, the change survives crashes and power loss.

How it's achieved:

  • The WAL is flushed to durable storage (fsync) before the commit is acknowledged.
  • Replication to other machines protects against losing a whole server or disk. Synchronous or majority-acknowledged replication means a committed write survives even if the primary is destroyed.

Durability can be relaxed for speed, for example PostgreSQL's synchronous_commit = off, or asynchronous replication. That accepts a risk of losing the most recent commits in exchange for lower latency. It's reasonable for some data, such as analytics events, and not for payments.

ACID in distributed systems and NoSQL

  • Single-node relational databases provide full ACID transactions across any tables.
  • MongoDB: a write to a single document is always atomic. Multi-document ACID transactions have been available since version 4.0, but they cost more, so schemas are designed to keep atomic changes within one document where possible.
  • Many NoSQL stores offer atomicity per key or partition only, and follow BASE: Basically Available, Soft state, Eventually consistent.
  • Across microservices, each service owns its own database, so no single ACID transaction spans them. Workflows use sagas (local transactions plus compensating actions) and the outbox pattern for reliable event publishing. Distributed SQL databases (Spanner, CockroachDB) do provide ACID across nodes, using consensus.

Follow-up questions this topic invites — and their answers

Q: What's the difference between atomicity and isolation? A: Atomicity concerns failure: a transaction's changes happen completely or not at all. Isolation concerns concurrency: how and when a transaction sees other transactions' changes while they run at the same time.

Q: How do databases guarantee atomicity and durability after a crash? A: With write-ahead logging. Changes are written to a durable log before being applied. On restart, the database replays the log, redoing committed transactions and rolling back incomplete ones. Commits are acknowledged only after the log is flushed.

Q: Why not always use Serializable isolation? A: It reduces concurrency. Depending on the implementation, it means more locking, or more transaction aborts that must be retried. Many workloads are safe under Read Committed with targeted techniques (row locks, atomic updates, constraints), and use Serializable only where anomalies like write skew are possible.

Q: How do you prevent lost updates without Serializable? A: Use an atomic update (SET balance = balance - 500), lock the row first (SELECT … FOR UPDATE), or use optimistic locking with a version column (UPDATE … WHERE id = ? AND version = ?, retrying if 0 rows are updated).

Q: How do you get ACID-like guarantees across microservices? A: You generally don't get a single ACID transaction. Use sagas with compensating actions for multi-step workflows, the transactional outbox pattern for reliable event publishing, and idempotent consumers. Accept eventual consistency between services, and keep invariants that need strong guarantees within one service's database.

Advertisement

Next

Indexes & Query Performance

AI Tutor

Lesson: ACID Properties

Quick actions

AI responses can be inaccurate. Verify critical information.