SQL: Incorrect by Construction

· databases design · Source ↗

TLDR

  • SQL’s default behavior makes it trivially easy to ship TOCTOU races, atomicity gaps, and deadlocks in transaction code that looks correct.

Key Takeaways

  • A textbook TSQL money-transfer procedure requires atomicity, UPDLOCK row locking, and upfront lock acquisition to be correct – three non-obvious steps.
  • TOCTOU bugs occur when a balance check and subsequent UPDATE run in separate steps without holding a lock across both.
  • Deadlocks emerge when concurrent transactions acquire row locks in different orders; ORDER BY does not reliably prevent this because locks follow row-read order, not result order.
  • The author proposes a Rust-inspired “fearless concurrency” database layer: atomic transactions by default, explicit checkpoints, user-managed locks, and static deadlock detection.
  • The proposed system trades throughput for correctness, leaving SQL in place for use cases where correctness is less critical.

Hacker News Comment Review

  • Commenters quickly noted the idiomatic fix the article downplays: a single UPDATE ... WHERE balance >= 10 collapses check and mutate atomically, eliminating TOCTOU without extra locking syntax.
  • One commenter flagged that append-only debit/credit ledger patterns make the problem worse – a SELECT-then-INSERT flow breaks ACID assumptions even when developers think they are safe.
  • There is skepticism that the framing is fair: SQL is a declarative query language, and using it for imperative transactional control is already outside its original design scope.

Notable Comments

  • @giancarlostoro: Caching layers and distributed systems can surface stale reads even after fixing DB-level concurrency, making the problem harder than the article’s scope.

Original | Discuss on HN