Intermediate: combining and changing data · Changing data, transactions and ACID · topic 40 of 62 · 35 min
Transactions: all or nothing
Explanation
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.
BEGIN, COMMIT and ROLLBACK
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- 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.
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.
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 undoneErrors 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.
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
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.
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;Practice (0/3 done)
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.
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.
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
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- ACID, isolation and lockingChanging data, transactions and ACID · same module
- UPDATE and DELETE safelyChanging data, transactions and ACID · same module
- Transactions and ACIDBackend Development · SQL in depth
- JDBC: talking to a databaseJava Programming (Core to Spring Boot) · JDBC, Maven, Gradle and JUnit
- Databases with database/sqlGo Programming (backend and cloud) · Building a REST API with a database
- Iterators: the glue between containers and algorithmsC++ Programming (modern C++ and DSA) · The Standard Template Library (STL)
Questions people ask about this
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.
Why use a transaction for a money transfer?Related
Answer: So the debit and credit succeed or fail together
Atomicity: all or nothing.
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.
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.
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 more topic in “Changing data, transactions and ACID” before its exam: ACID, isolation and locking.
- Module 8 exam: Changing data, transactions and ACID · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Schema design and normalisation. 62 topics left in the course before the final exam.