Example 1
Insert two rows, roll back only the second, and commit the first
The transaction inserts action_a, then sets a savepoint. It inserts action_b, then rolls back to the savepoint — undoing action_b only. The transaction is then committed, making action_a permanent. The pre-existing session_start row is unaffected because it was inserted before the transaction began. The final table contains only session_start and action_a.
CREATE TABLE audit_log (id INT, event VARCHAR(50));
INSERT INTO
audit_log (id, event)
VALUES
(1, 'session_start');START TRANSACTION;
INSERT INTO
audit_log (id, event)
VALUES
(2, 'action_a');
SAVEPOINT after_action_a;
INSERT INTO
audit_log (id, event)
VALUES
(3, 'action_b');
ROLLBACK TO SAVEPOINT after_action_a;
COMMIT;
SELECT
id,
event
FROM
audit_log
ORDER BY
id;| id | event |
|---|---|
| 1 | session_start |
| 2 | action_a |
CREATE TABLE audit_log (id INT, event VARCHAR(50));
INSERT INTO
audit_log (id, event)
VALUES
(1, 'session_start');BEGIN TRANSACTION;
INSERT INTO
audit_log (id, event)
VALUES
(2, 'action_a');
SAVE TRANSACTION after_action_a;
INSERT INTO
audit_log (id, event)
VALUES
(3, 'action_b');
ROLLBACK TRANSACTION after_action_a;
COMMIT;
SELECT
id,
event
FROM
audit_log
ORDER BY
id;| id | event |
|---|---|
| 1 | session_start |
| 2 | action_a |
CREATE TABLE audit_log (id INT, event VARCHAR(50));
INSERT INTO
audit_log (id, event)
VALUES
(1, 'session_start');BEGIN;
INSERT INTO
audit_log (id, event)
VALUES
(2, 'action_a');
SAVEPOINT after_action_a;
INSERT INTO
audit_log (id, event)
VALUES
(3, 'action_b');
ROLLBACK TO SAVEPOINT after_action_a;
COMMIT;
SELECT
id,
event
FROM
audit_log
ORDER BY
id;| id | event |
|---|---|
| 1 | session_start |
| 2 | action_a |
MySQL, MariaDB, PostgreSQL, and SQLite use SAVEPOINT and ROLLBACK TO SAVEPOINT. SQL Server uses SAVE TRANSACTION and ROLLBACK TRANSACTION with the same savepoint name. The resulting table state is identical: action_b was rolled back, action_a was committed.