Skip to content

What is a transaction? ​

A transaction groups transactional database work that commits together or is discarded by rollback. The two-account transfer demonstrations assert the original balances after rollback on PostgreSQL and MySQL InnoDB. This boundary excludes external effects, PostgreSQL sequence counters, nontransactional MySQL tables, and operations that cause implicit commits.

ACID ​

PropertyScoped meaningSupport
AtomicityTransactional table changes share commit/rollbackThe two linked transfer Scenarios assert explicit rollback, not every failure
ConsistencyDeclared constraints and correct serial transaction logic preserve their stated rulesCHECK failures are demonstrated; arbitrary application rules are not automatic
IsolationConcurrent operations follow the engine's selected isolation contractLevels, assertions, manual contracts, and marked derivations
DurabilityAcknowledged persistence depends on durability settings and storage behaviorDocumented support below; no server-crash experiment here

Atomicity does not mean all statements succeed or every reader sees the same values. A failed InnoDB statement can leave earlier work to be committed unless the transaction is rolled back. READ UNCOMMITTED can expose uncommitted changes. Isolation and error handling therefore need their own conditions.

A business invariant requires each serial transaction to preserve it and all relevant writers to use an appropriate protocol. A CHECK on one balance does not enforce an arbitrary cross-row rule or an external payment boundary.

Durability is a documented contract, not a claimed crash test. The PostgreSQL 18 asynchronous-commit manual warns that "the most recent transactions may be lost if the database should crash." MySQL 8.4's ACID manual states: "The durability aspect of the ACID model involves MySQL software features interacting with your particular hardware configuration." Its InnoDB conditions include innodb_flush_log_at_trx_commit, sync_binlog, operating-system fsync() support, and storage write buffers. A successful COMMIT in these demonstrations does not test crash recovery, storage reliability, or every configuration.

Same promise, different temperament ​

  • PostgreSQL: an ordinary statement error inside BEGIN leaves a failed transaction block. Ordinary statements fail until full rollback or recovery to a valid savepoint. A standalone failed statement ends its implicit transaction. See error-state assertions and savepoint recovery. Connection loss is a separate case.
  • MySQL InnoDB: the demonstrated CHECK/duplicate-key errors roll back the statement, retaining earlier work until explicit rollback or commit. Deadlocks roll back the transaction; row-lock timeout rollback depends on innodb_rollback_on_timeout. The 8.4 error manual states for a deadlock: "Retry the entire transaction when this happens." See the basic error schedule and timeout scope.

Complete-operation retries need fresh reads and decisions, a bound, and a separate policy for effects outside the database transaction. Neither engine promises every retry succeeds.

See it happen ​

  • PostgreSQL transfer: CHECK failure and full rollback, with another session excluding the uncommitted credit at READ COMMITTED.
  • MySQL transfer: the failed debit leaves the earlier credit visible to its own transaction until explicit rollback.

MIT Licensed · Every transcript on this site was generated by a real database run against MySQL 8.4.11 and PostgreSQL 18.6 at 8fa27b8; shared YAML has an independent psycopg/PyMySQL check.