描述

回滚一个事务指将事务的修改全部撤销。可以回滚当前整个未提交事务,也可以回滚到事务中任意一个保存点。如果要回滚到某个保存点,必须将 ROLLBACKTO SAVEPOINT 语句结合使用。

如果回滚整个事务:

  • 事务会结束。

  • 所有的修改会被丢弃。

  • 清除所有保存点。

  • 释放事务持有的所有锁。

如果回滚到某个保存点:

  • 事务不会结束。

  • 保存点之前的修改被保留,保存点之后的修改被丢弃。

  • 清除保存点之后的保存点(不包括保存点自身)。

  • 释放保存点之后事务持有的所有锁。

回滚整个事务

回滚整个事务的示例如下:

  • MySQL 模式下,回滚事务的全部修改。

    1. obclient> SELECT * FROM t_insert;
    2. +----+------+-------+---------------------+
    3. | ID | NAME | VALUE | GMT_CREATE |
    4. +----+------+-------+---------------------+
    5. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    6. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    7. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    8. +----+------+-------+---------------------+
    9. 3 rows in set (0.00 sec)
    10. obclient> BEGIN;
    11. Query OK, 0 rows affected (0.00 sec)
    12. obclient> INSERT INTO t_insert(id, name, value) VALUES(4,'JP',10004);
    13. Query OK, 1 row affected (0.00 sec)
    14. obclient> INSERT INTO t_insert(id, name, value) VALUES(5,'FR',10005),(6,'RU',10006);
    15. Query OK, 2 rows affected (0.00 sec)
    16. Records: 2 Duplicates: 0 Warnings: 0
    17. obclient> SELECT * FROM t_insert;
    18. +----+------+-------+---------------------+
    19. | ID | NAME | VALUE | GMT_CREATE |
    20. +----+------+-------+---------------------+
    21. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    22. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    23. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    24. | 4 | JP | NULL | 2020-04-02 17:53:34 |
    25. | 5 | FR | 10005 | 2020-04-02 17:54:53 |
    26. | 6 | RU | 10006 | 2020-04-02 17:54:53 |
    27. +----+------+-------+---------------------+
    28. 6 rows in set (0.00 sec)
    29. obclient> ROLLBACK;
    30. Query OK, 0 rows affected (0.00 sec)
    31. obclient> SELECT * FROM t_insert;
    32. +----+------+-------+---------------------+
    33. | ID | NAME | VALUE | GMT_CREATE |
    34. +----+------+-------+---------------------+
    35. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    36. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    37. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    38. +----+------+-------+---------------------+
    39. 3 rows in set (0.00 sec)
  • Oracle 模式下,回滚事务的全部修改。

    1. obclient> SELECT * FROM t_insert;
    2. +----+------+-------+---------------------+
    3. | ID | NAME | VALUE | GMT_CREATE |
    4. +----+------+-------+---------------------+
    5. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    6. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    7. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    8. +----+------+-------+---------------------+
    9. 3 rows in set (0.00 sec)
    10. obclient> INSERT INTO t_insert(id, name, value) VALUES(4,'JP',10004);
    11. Query OK, 1 row affected (0.00 sec)
    12. obclient> INSERT INTO t_insert(id, name, value) VALUES(5,'FR',10005),(6,'RU',10006);
    13. Query OK, 2 rows affected (0.00 sec)
    14. Records: 2 Duplicates: 0 Warnings: 0
    15. obclient> SELECT * FROM t_insert;
    16. +----+------+-------+---------------------+
    17. | ID | NAME | VALUE | GMT_CREATE |
    18. +----+------+-------+---------------------+
    19. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    20. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    21. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    22. | 4 | JP | NULL | 2020-04-02 17:53:34 |
    23. | 5 | FR | 10005 | 2020-04-02 17:54:53 |
    24. | 6 | RU | 10006 | 2020-04-02 17:54:53 |
    25. +----+------+-------+---------------------+
    26. 6 rows in set (0.00 sec)
    27. obclient> ROLLBACK;
    28. Query OK, 0 rows affected (0.00 sec)
    29. obclient> SELECT * FROM t_insert;
    30. +----+------+-------+---------------------+
    31. | ID | NAME | VALUE | GMT_CREATE |
    32. +----+------+-------+---------------------+
    33. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
    34. | 2 | US | 10002 | 2020-04-02 17:52:38 |
    35. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
    36. +----+------+-------+---------------------+
    37. 3 rows in set (0.00 sec)

回滚到某个保存点

以下示例展示了一个事务中包含多个 DML 语句和多个保存点,当回滚到其中一个保存点后,仅丢弃了保存点后面的那部分修改。

  • MySQL 模式

    1. 查看表当前记录。

      1. obclient> SELECT * FROM t_insert;
      2. +----+------+-------+---------------------+
      3. | id | name | value | gmt_create |
      4. +----+------+-------+---------------------+
      5. | 1 | CN | 10001 | 2020-04-03 16:05:45 |
      6. | 2 | US | 10002 | 2020-04-03 16:05:54 |
      7. | 3 | UK | 10003 | 2020-04-03 16:05:54 |
      8. +----+------+-------+---------------------+
      9. 3 rows in set (0.00 sec)
    2. 开启一个事务,设置多个保存点信息。

      1. obclient> SET SESSION autocommit=off;
      2. Query OK, 0 rows affected (0.00 sec)
      3. obclient> BEGIN;
      4. Query OK, 0 rows affected (0.00 sec)
      5. obclient> INSERT INTO t_insert(id, name) VALUES(6,'FR');
      6. Query OK, 1 row affected (0.00 sec)
      7. obclient> SAVEPOINT fr;
      8. Query OK, 0 rows affected (0.00 sec)
      9. obclient> INSERT INTO t_insert(id, name) VALUES(7,'RU');
      10. Query OK, 1 row affected (0.00 sec)
      11. obclient> SAVEPOINT ru;
      12. Query OK, 0 rows affected (0.00 sec)
      13. obclient> INSERT INTO t_insert(id, name) VALUES(8,'CA');
      14. Query OK, 1 row affected (0.00 sec)
      15. obclient> SAVEPOINT ca;
      16. Query OK, 0 rows affected (0.00 sec)
    3. 查看当前会话中,事务未提交的所有修改。

      1. obclient> SELECT * FROM t_insert;
      2. +----+------+-------+---------------------+
      3. | id | name | value | gmt_create |
      4. +----+------+-------+---------------------+
      5. | 1 | CN | 10001 | 2020-04-03 16:05:45 |
      6. | 2 | US | 10002 | 2020-04-03 16:05:54 |
      7. | 3 | UK | 10003 | 2020-04-03 16:05:54 |
      8. | 6 | FR | NULL | 2020-04-03 16:26:22 |
      9. | 7 | RU | NULL | 2020-04-03 16:26:32 |
      10. | 8 | CA | NULL | 2020-04-03 16:26:42 |
      11. +----+------+-------+---------------------+
      12. 6 rows in set (0.00 sec)
    4. 回滚事务到其中一个保存点。

      1. obclient> ROLLBACK TO SAVEPOINT ru;
      2. Query OK, 0 rows affected (0.00 sec)
      3. obclient> SELECT * FROM t_insert;
      4. +----+------+-------+---------------------+
      5. | id | name | value | gmt_create |
      6. +----+------+-------+---------------------+
      7. | 1 | CN | 10001 | 2020-04-03 16:05:45 |
      8. | 2 | US | 10002 | 2020-04-03 16:05:54 |
      9. | 3 | UK | 10003 | 2020-04-03 16:05:54 |
      10. | 6 | FR | NULL | 2020-04-03 16:26:22 |
      11. | 7 | RU | NULL | 2020-04-03 16:26:32 |
      12. +----+------+-------+---------------------+
      13. 5 rows in set (0.01 sec)
    5. 提交事务,确认表最新修改包含保存点之前的修改。

      1. obclient> COMMIT;
      2. Query OK, 0 rows affected (0.00 sec)
      3. obclient> SELECT * FROM t_insert;
      4. +----+------+-------+---------------------+
      5. | id | name | value | gmt_create |
      6. +----+------+-------+---------------------+
      7. | 1 | CN | 10001 | 2020-04-03 16:05:45 |
      8. | 2 | US | 10002 | 2020-04-03 16:05:54 |
      9. | 3 | UK | 10003 | 2020-04-03 16:05:54 |
      10. | 6 | FR | NULL | 2020-04-03 16:26:22 |
      11. | 7 | RU | NULL | 2020-04-03 16:26:32 |
      12. +----+------+-------+---------------------+
      13. 5 rows in set (0.00 sec)
  • Oracle 模式

    1. 查看表当前记录。

      1. obclient> SELECT * FROM t_insert;
      2. +----+------+-------+---------------------+
      3. | ID | NAME | VALUE | GMT_CREATE |
      4. +----+------+-------+---------------------+
      5. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
      6. | 2 | US | 10002 | 2020-04-02 17:52:38 |
      7. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
      8. | 4 | JP | NULL | 2020-04-02 17:53:34 |
      9. | 5 | DE | NULL | 2020-04-02 17:58:31 |
      10. +----+------+-------+---------------------+
      11. 5 rows in set (0.00 sec)
    2. 开启一个事务,设置多个保存点信息。

      1. obclient> INSERT INTO t_insert(id, name) VALUES(6,'FR');
      2. Query OK, 1 row affected (0.00 sec)
      3. obclient> SAVEPOINT fr;
      4. Query OK, 0 rows affected (0.00 sec)
      5. obclient> INSERT INTO t_insert(id, name) VALUES(7,'RU');
      6. Query OK, 1 row affected (0.00 sec)
      7. obclient> SAVEPOINT ru;
      8. Query OK, 0 rows affected (0.00 sec)
      9. obclient> INSERT INTO t_insert(id, name) VALUES(8,'CA');
      10. Query OK, 1 row affected (0.00 sec)
      11. obclient> SAVEPOINT ca;
      12. Query OK, 0 rows affected (0.00 sec)
    3. 当前会话中能看到事务未提交的所有修改。

      1. obclient> SELECT * FROM t_insert;
      2. +----+------+-------+---------------------+
      3. | ID | NAME | VALUE | GMT_CREATE |
      4. +----+------+-------+---------------------+
      5. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
      6. | 2 | US | 10002 | 2020-04-02 17:52:38 |
      7. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
      8. | 4 | JP | NULL | 2020-04-02 17:53:34 |
      9. | 5 | DE | NULL | 2020-04-02 17:58:31 |
      10. | 6 | FR | NULL | 2020-04-02 17:58:59 |
      11. | 7 | RU | NULL | 2020-04-02 17:59:09 |
      12. | 8 | CA | NULL | 2020-04-02 17:59:19 |
      13. +----+------+-------+---------------------+
      14. 8 rows in set (0.00 sec)
    4. 回滚事务到其中一个保存点。

      1. obclient> ROLLBACK TO SAVEPOINT ru;
      2. Query OK, 0 rows affected (0.00 sec)
      3. obclient> SELECT * FROM t_insert;
      4. +----+------+-------+---------------------+
      5. | ID | NAME | VALUE | GMT_CREATE |
      6. +----+------+-------+---------------------+
      7. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
      8. | 2 | US | 10002 | 2020-04-02 17:52:38 |
      9. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
      10. | 4 | JP | NULL | 2020-04-02 17:53:34 |
      11. | 5 | DE | NULL | 2020-04-02 17:58:31 |
      12. | 6 | FR | NULL | 2020-04-02 17:58:59 |
      13. | 7 | RU | NULL | 2020-04-02 17:59:09 |
      14. +----+------+-------+---------------------+
      15. 7 rows in set (0.00 sec)
    5. 提交事务,确认表最新修改包含保存点之前的修改。

      1. obclient> COMMIT;
      2. Query OK, 0 rows affected (0.00 sec)
      3. obclient> SELECT * FROM t_insert;
      4. +----+------+-------+---------------------+
      5. | ID | NAME | VALUE | GMT_CREATE |
      6. +----+------+-------+---------------------+
      7. | 1 | CN | 10001 | 2020-04-02 17:52:31 |
      8. | 2 | US | 10002 | 2020-04-02 17:52:38 |
      9. | 3 | EN | 10003 | 2020-04-02 17:52:38 |
      10. | 4 | JP | NULL | 2020-04-02 17:53:34 |
      11. | 5 | DE | NULL | 2020-04-02 17:58:31 |
      12. | 6 | FR | NULL | 2020-04-02 17:58:59 |
      13. | 7 | RU | NULL | 2020-04-02 17:59:09 |
      14. +----+------+-------+---------------------+
      15. 7 rows in set (0.00 sec)