ACID Properties
debt(d5/e3/b5/t6)
Closest to 'specialist tool catches it' (d5). The detection_hints list semgrep and phpstan as tools that can detect multiple related INSERT/UPDATE/DELETE statements without wrapping transactions. This is a pattern-based detection that requires specialist static analysis tooling — default linters won't catch missing transaction boundaries, but SAST tools like semgrep with custom rules can flag the common case of unwrapped multi-step writes.
Closest to 'simple parameterised fix' (e3). The quick_fix is 'wrap related database operations in a transaction — if any step fails, rollback ensures the database stays consistent.' This is typically a localized fix within one file or service method — adding BEGIN/COMMIT/ROLLBACK around existing queries. It's more than a one-line patch (e1) since you need to add try/catch logic and rollback handling, but it's a well-understood pattern that doesn't span multiple files in most cases.
Closest to 'persistent productivity tax' (b5). ACID awareness applies across all contexts (web, cli, queue-worker) per the applies_to field. The decision about transaction boundaries and isolation levels is not a one-time architectural choice but a persistent concern: every new feature that touches multiple tables must consider transactional wrapping, and choosing the wrong default isolation level has systemic implications. It doesn't quite define the system's shape (b9) but it does slow down many work streams as developers must consistently reason about transaction boundaries.
Closest to 'notable trap' (t5), scored +1 to t6. The misconception states that 'All databases claiming ACID compliance provide the same guarantees' — this is a significant trap because developers commonly assume ACID is binary (you have it or you don't), when in reality isolation levels (READ COMMITTED vs REPEATABLE READ vs SERIALIZABLE) vary dramatically in behavior. Additionally, common_mistakes include assuming NoSQL databases are ACID and using READ UNCOMMITTED. This goes slightly beyond a 'documented gotcha most devs eventually learn' (t5) because the trap involves multiple layers of false confidence — believing you have ACID, not understanding which isolation level you're running, and not realizing different engines behave differently under the same ACID label.
Also Known As
TL;DR
Explanation
ACID ensures reliable transaction processing: Atomicity — a transaction either fully succeeds or fully rolls back (no partial writes); Consistency — the database moves from one valid state to another, enforcing constraints; Isolation — concurrent transactions don't see each other's intermediate state (controlled by isolation levels: Read Uncommitted, Read Committed, Repeatable Read, Serializable); Durability — committed transactions survive crashes (via write-ahead logging). In PHP, manage transactions explicitly with PDO::beginTransaction(), commit(), and rollBack(), especially when multiple related writes must succeed together.
Diagram
flowchart TD
subgraph ACID
A[Atomicity<br/>all or nothing<br/>no partial writes]
C[Consistency<br/>business rules<br/>always maintained]
I[Isolation<br/>concurrent transactions<br/>don't interfere]
D[Durability<br/>committed data<br/>survives crashes]
end
TRANS[Database Transaction] --> A & C & I & D
FAIL[Power failure<br/>during write] -->|redo log| D
CONC[Concurrent writes] -->|locks + MVCC| I
style A fill:#238636,color:#fff
style C fill:#238636,color:#fff
style I fill:#1f6feb,color:#fff
style D fill:#6e40c9,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Assuming NoSQL databases are ACID — most sacrifice isolation or durability for performance.
- Not wrapping multi-step operations in a transaction — a crash between steps leaves data inconsistent.
- Using READ UNCOMMITTED isolation — allows dirty reads of data that may be rolled back.
- Relying on application-level locking instead of database transactions for concurrency.
Avoid When
- You need horizontal scalability across distributed nodes — full ACID across shards requires coordination overhead.
- The workload tolerates eventual consistency — sacrificing isolation for availability (BASE model) may be correct.
- Using NoSQL stores that offer only document-level atomicity — do not assume full ACID without verifying.
When To Use
- Financial transactions, inventory management, or any domain where partial writes are catastrophic.
- Any operation touching multiple rows or tables that must succeed or fail atomically.
- Concurrent workloads where isolation prevents dirty reads and phantom reads.
- Systems where durability guarantees are required — data must survive a crash without loss.
Code Examples
// Two separate queries without a transaction — partial failure leaves inconsistent state
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
try {
$pdo->beginTransaction();
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack(); throw $e;
}