SQL / CHAPTER 13

Transactions, constraints, and query plans

Advanced

Protect data invariants and investigate performance with evidence.

By the end of this chapter

  • Use a transaction for an all-or-nothing change
  • Enforce suitable invariants with constraints
  • Read query plans without depending on their exact text

The idea

SQLite transactions group changes into a unit that can be committed or rolled back. This matters when several statements jointly maintain an invariant, such as transferring a quantity between records. Application code must still detect failure and choose rollback; merely issuing BEGIN does not prove a business rule was preserved. Constraints provide another line of defense for invariants that the database can express.

An index can speed selective lookups and some ordering operations, but it consumes storage and adds maintenance work to writes. Choose it from observed query patterns and inspect EXPLAIN QUERY PLAN rather than assuming every index helps. Plan text and optimizer choices can change, so test query results independently of plan formatting. Transaction and schema examples belong in a SQLite environment that permits writes; they are separate from read-only exercises.

SQL example
CREATE TEMP TABLE balances(id INTEGER PRIMARY KEY, amount INTEGER NOT NULL CHECK(amount >= 0));
INSERT INTO balances VALUES(1,10),(2,0);
BEGIN;
UPDATE balances SET amount=amount-3 WHERE id=1;
UPDATE balances SET amount=amount+3 WHERE id=2;
COMMIT;
SELECT id,amount FROM balances ORDER BY id;
Result
id | amount
1  | 7
2  | 3

Both updates commit as one unit and preserve the total of ten. The CHECK constraint separately rejects a negative stored amount.

Try it yourself

Describe a transfer operation that verifies sufficient funds and rolls back on failure, then suggest an index for lookup by account id.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

Open SQL coding challenges

CHECK YOUR UNDERSTANDING

Chapter checkpoint

What operation abandons the changes of an active transaction?