Skip to content

Intermediate: combining and changing data · Changing data, transactions and ACID · topic 40 of 62 · 35 min

Transactions: all or nothing

Explanation

A transaction groups several statements so they succeed or fail together. BEGIN starts it, COMMIT makes the changes permanent, and ROLLBACK undoes everything since BEGIN. A money transfer, a debit and a credit, must be one transaction. Without BEGIN, each statement commits on its own (autocommit). SAVEPOINT lets you undo part of a transaction.

Why transactions?

Sending ₹1500 over UPI from Asha to Ravi is two changes: subtract 1500 from Asha's account and add 1500 to Ravi's. If the server crashes after the first step, Asha has lost money that Ravi never got. A transaction is a group of statements that the database treats as one unit: either all of them take effect, or none of them do.

Think of it like this: Think of a transaction like filling a form at a bank counter. You can write, cross out and correct as much as you like, and nothing happens until you sign and hand it over (COMMIT). If you tear the form up (ROLLBACK), it is as if you never started.

BEGIN, COMMIT and ROLLBACK

sql
BEGIN;
UPDATE accounts SET balance = balance - 1500 WHERE id = 1;   -- Asha
UPDATE accounts SET balance = balance + 1500 WHERE id = 2;   -- Ravi
INSERT INTO transfers (from_id, to_id, amount) VALUES (1, 2, 1500);
COMMIT;
SELECT id, holder, balance FROM accounts;
-- 1 | Asha Verma | 3500
-- 2 | Ravi Kumar | 4500
-- 3 | Priya Nair | 1200
Other connections see none of these changes until COMMIT, and then all of them at once.
  • BEGIN (or BEGIN TRANSACTION; START TRANSACTION in MySQL and PostgreSQL; BEGIN TRAN in SQL Server) starts a transaction.
  • COMMIT makes every change since BEGIN permanent and visible to others.
  • ROLLBACK throws away every change since BEGIN, as if it never happened.
sql
BEGIN;
UPDATE accounts SET balance = balance - 4000 WHERE id = 1;
UPDATE accounts SET balance = balance + 4000 WHERE id = 3;
ROLLBACK;     -- the payment gateway reported a failure
SELECT id, balance FROM accounts;
-- 1 | 5000 ,  2 | 3000 ,  3 | 1200   (unchanged)

Autocommit

If you never write BEGIN, SQLite, PostgreSQL, MySQL and SQL Server run each statement in its own tiny transaction and commit it straight away. This is called autocommit. It is fine for a single statement, but two related statements in autocommit mode are two separate transactions, and a crash between them leaves half the work done. Some tools, such as Oracle SQL*Plus and many database GUIs set to manual commit, work the other way: nothing is saved until you COMMIT. Know which mode your tool is in.

SAVEPOINT: undo part of the work

A savepoint is a named marker inside a transaction. ROLLBACK TO name undoes the work done after the marker but keeps what came before, and the transaction carries on. RELEASE name removes the marker. SQLite, PostgreSQL and MySQL use these words; SQL Server writes SAVE TRANSACTION name and ROLLBACK TRANSACTION name.

sql
BEGIN;
UPDATE accounts SET balance = balance - 1000 WHERE id = 1;
UPDATE accounts SET balance = balance + 1000 WHERE id = 2;
SAVEPOINT cashback;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;   -- offer not valid after all
ROLLBACK TO cashback;
COMMIT;
-- Asha 4000, Ravi 4000: the transfer stays, the cashback is undone

Errors inside a transaction

What happens when one statement fails depends on the engine. The accounts table has CHECK (balance >= 0), so taking 2000 from Priya's 1200 fails with "CHECK constraint failed: balance >= 0".

  • SQLite and MySQL: by default only the failing statement is undone. The transaction stays open, and the earlier statements are still pending. Your code must decide to ROLLBACK.
  • PostgreSQL: the whole transaction becomes unusable. Every next statement fails with "current transaction is aborted, commands ignored until end of transaction block" until you ROLLBACK (or ROLLBACK TO a savepoint).
  • SQL Server: depends on the setting XACT_ABORT; with SET XACT_ABORT ON, most errors roll back the whole transaction.

The safe rule for app code in every language: start the transaction, run the statements, COMMIT; if anything throws an error, ROLLBACK. Most database libraries have a helper for exactly this, such as a "with" block in Python or a transaction function in Node.js ORMs.

Tip: Transactions also make bulk work faster. In SQLite, inserting 10,000 rows in autocommit mode means 10,000 commits, each waiting for the disk; wrapped in one BEGIN ... COMMIT it is one commit and runs many times faster.

Common mistakes

  • Running related statements without BEGIN, so a failure in the middle leaves half the work saved.
  • Forgetting COMMIT. The changes stay invisible to others and may be thrown away when the connection closes, and the open transaction can block other writers.
  • Keeping a transaction open while waiting for a user or a slow API call. Keep transactions short.
  • Ignoring errors and committing anyway. On any error, ROLLBACK.
  • Expecting DDL (CREATE, ALTER, DROP) to roll back in MySQL. MySQL commits automatically before such statements; PostgreSQL and SQLite can roll them back.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Transactions: all or nothing · 1/7

Transactions: all or nothing

Sending money is two changes: a debit and a credit. If only one happens, money is lost. Transactions prevent that.

Prefer a video by a teacher? Find free videos on “sql transactions begin commit rollback savepoint explained” on YouTube ↗

In real life: A UPI-style payment between two banks

In a real payment between two banks, each bank runs its own transactions and a central switch coordinates them with messages, reference numbers and reversals; the details are complex and not public. Inside a single bank's database, though, the rule is simple: the debit, the credit and the ledger entry go in one transaction, so a crash can never leave money missing.

sql
BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE id = 2;
UPDATE accounts SET balance = balance + 500 WHERE id = 3;
INSERT INTO transfers (from_id, to_id, amount) VALUES (2, 3, 500);
COMMIT;
Ravi pays Priya 500: both balances and the log change together, or not at all.

Practice (0/3 done)

Task 1 · Code · SQL

Transfer 1500 from account 1 (Asha) to account 2 (Ravi) inside BEGIN ... COMMIT, and inside the same transaction record it in transfers (from_id, to_id, amount). After the COMMIT, return id, holder and balance of all accounts.

Task 2 · Code · SQL

Run two transactions. First: move 500 from account 2 to account 3 and COMMIT. Second: start moving 4000 from account 1 to account 3, but then ROLLBACK because the payment failed. Finally return id and balance of all accounts.

Task 3 · Code · SQL

In one transaction: move 1000 from account 1 to account 2, then create a SAVEPOINT named cashback, then add 50 to account 1 as cashback. The cashback offer turns out to be invalid: ROLLBACK TO cashback, then COMMIT. Return id and balance of all accounts.

Quick quiz

Question 1

1.BEGIN; UPDATE A; UPDATE B; ROLLBACK; What is saved?

Question 2

2.What is autocommit?

Question 3

3.Inside a transaction you run SAVEPOINT s1, then an UPDATE, then ROLLBACK TO s1. What happens?

Question 4

4.In PostgreSQL, a statement inside your transaction fails. What must you do before running more statements?

Question 5

5.Why should a transaction not stay open while the app waits for the user to click "Confirm"?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

BEGIN; UPDATE A; UPDATE B; ROLLBACK; What is saved?

Answer: Nothing; both updates are undone

ROLLBACK undoes everything since BEGIN.

What is autocommit?

Answer: Each statement is committed on its own as soon as it finishes

Without BEGIN, every statement is its own transaction.

Inside a transaction you run SAVEPOINT s1, then an UPDATE, then ROLLBACK TO s1. What happens?

Answer: Only the work after s1 is undone, and the transaction stays open

ROLLBACK TO undoes back to the marker and keeps the earlier work pending.

In PostgreSQL, a statement inside your transaction fails. What must you do before running more statements?

Answer: ROLLBACK (or ROLLBACK TO a savepoint)

PostgreSQL marks the transaction as aborted and ignores further commands until you roll back.

Why should a transaction not stay open while the app waits for the user to click "Confirm"?

Answer: It may hold locks for a long time and block other users

Open transactions hold locks; keep them short and do the waiting outside.

Why should you not send an SMS from inside an open transaction?Related

Answer: The slow call keeps locks held and makes other users wait; and the SMS cannot be rolled back

Transactions should be short. Outside calls are slow, and an SMS already sent cannot be undone by ROLLBACK.

From Transactions and ACID

Why use a transaction for a money transfer?Related

Answer: So the debit and credit succeed or fail together

Atomicity: all or nothing.

From JDBC: talking to a database

Which statement locks the rows you read until your transaction ends, in PostgreSQL and MySQL?Related

Answer: SELECT ... FOR UPDATE

FOR UPDATE takes row locks. SQLite does not support it.

From ACID, isolation and locking

Why defer tx.Rollback() right after BeginTx?Related

Answer: So any early return rolls back; after Commit it does nothing

Rollback after a successful Commit just returns sql.ErrTxDone, which is safe to ignore.

From Databases with database/sql

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Changing data, transactions and ACID” before its exam: ACID, isolation and locking.
  2. Module 8 exam: Changing data, transactions and ACID · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Schema design and normalisation. 62 topics left in the course before the final exam.

← Previous: Upserts: insert or update