事务

事务是用户定义的一个数据库操作序列,这些操作要么全做要么全不做,是一个不可分割的工作单位。openGauss数据库支持的事务控制命令有启动、设置、提交、回滚事务。openGauss数据库支持的事务隔离级别有读已提交和可重复读。

  • READ COMMITTED:读已提交隔离级别,事务只能读到已提交的数据而不会读到未提交的数据,这是缺省值。

    实际上,SELECT查询会查看到在查询开始运行的瞬间该数据库的一个快照。不过,SELECT能查看到其自身所在事务中先前更新的执行结果。即使先前更新尚未提交。请注意,在同一个事务里两个相邻的SELECT命令可能会查看到不同的快照,因为其它事务会在第一个SELECT执行期间提交。

    因为在读已提交模式里,每个新的命令都是从一个新的快照开始的,而这个快照包含所有到该时刻为止已提交的事务,因此同一事务中后面的命令将看到任何已提交的其它事务的效果。这里关心的问题是在单个命令里是否看到数据库里绝对一致的视图。

    读已提交模式提供的部分事务隔离对于许多应用而言是足够的,并且这个模式速度快,使用简单。不过,对于做复杂查询和更新的应用,可能需要保证数据库有比读已提交模式更加严格的一致性视图。

  • REPEATABLE READ:事务可重复读隔离级别,事务只能读到事务开始之前已提交的数据,不能读到未提交的数据以及事务执行期间其它并发事务提交的修改(但是,查询能查看到自身所在事务中先前更新的执行结果,即使先前更新尚未提交)。这个级别和读已提交是不一样的,因为可重复读事务中的查询看到的是事务开始时的快照,不是该事务内部当前查询开始时的快照,就是说,单个事务内部的select命令总是查看到同样的数据,查看不到自身事务开始之后其他并发事务修改后提交的数据。使用该级别的应用必须准备好重试事务,因为可能会发生串行化失败。

语法格式

  • 启动事务

    使用BEGIN语法启动事务。

    1. BEGIN [ WORK | TRANSACTION ]
    2. [
    3. {
    4. ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ }
    5. | { READ WRITE | READ ONLY }
    6. } [, ...]
    7. ];

    使用START TRANSACTION启动事务。

    1. START TRANSACTION
    2. [
    3. {
    4. ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ }
    5. | { READ WRITE | READ ONLY }
    6. } [, ...]
    7. ];
  • 设置事务特性

    用户可以使用SET TRANSACTION或语法设置事务的隔离级别、读写模式。

    1. { SET [ LOCAL ] TRANSACTION|SET SESSION CHARACTERISTICS AS TRANSACTION }
    2. { ISOLATION LEVEL { READ COMMITTED | SERIALIZABLE | REPEATABLE READ }
    3. | { READ WRITE | READ ONLY } } [, ...];
  • 提交事务

    用户可以使用COMMIT或者END完成提交事务的功能,即提交事务的所有操作。

    1. { COMMIT | END } [ WORK | TRANSACTION ] ;
  • 回滚事务

    回滚是在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已完成的操作全部撤销。

    1. ROLLBACK [ WORK | TRANSACTION ];

参数说明

  • WORK | TRANSACTION

    BEGIN格式中的可选关键字,没有实际作用。

  • ISOLATION LEVEL

    指定事务隔离级别,它决定当一个事务中存在其他并发运行事务时它能够看到什么数据。

    事务 - 图1 说明: 在事务中第一个数据修改语句(SELECT, INSERT,DELETE,UPDATE,FETCH,COPY)执行之后,事务隔离级别就不能再次设置。

    取值范围:

    • READ COMMITTED:读已提交隔离级别,只能读到已经提交的数据,而不会读到未提交的数据。这是缺省值。
    • REPEATABLE READ: 可重复读隔离级别,仅仅看到事务开始之前提交的数据,它不能看到未提交的数据,以及在事务执行期间由其它并发事务提交的修改。
    • SERIALIZABLE:目前功能上不支持此隔离级别,等价于REPEATABLE READ。
  • READ WRITE | READ ONLY

    指定事务访问模式(读/写或者只读)。

  • LOCAL

    声明该命令只在当前事务中有效。

  • SESSION

    声明这个命令只对当前会话起作用。

    取值范围:字符串,要符合标识符的命名规范。

  • COMMIT | END

    提交当前事务,让所有当前事务的更改为其他事务可见。

示例

假设存在表customer_t1 ,数据内容如下:

  1. openGauss=# SELECT * FROM customer_t1;
  2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
  3. ---------------+---------------+--------------+-------------+--------
  4. 3769 | hello | Grace | | 1000
  5. 3769 | | Grace | |
  6. 3769 | hello | | |
  7. 6885 | maps | Joes | | 2200
  8. 4321 | tpcds | Lily | | 3000
  9. 9527 | world | James | | 5000
  10. (6 rows)

开启一个事务,并从表中删除amount为1000的行,最后使用ROLLBACK命令撤销所有的更改。

  1. openGauss=# START TRANSACTION;
  2. openGauss=# DELETE FROM customer_t1 WHERE amount = 1000;
  3. openGauss=# ROLLBACK;

查看表customer_t1,amount为1000的行仍然存在。

  1. openGauss=# select * from customer_t1;
  2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
  3. ---------------+---------------+--------------+-------------+--------
  4. 3769 | hello | Grace | | 1000
  5. 3769 | | Grace | |
  6. 3769 | hello | | |
  7. 6885 | maps | Joes | | 2200
  8. 4321 | tpcds | Lily | | 3000
  9. 9527 | world | James | | 5000
  10. (6 rows)

开始另一个事务,从表中删除amount=1000的记录,最后使用COMMIT命令提交所有的更改。

  1. --开启一个事务,设置事务的隔离级别为READ COMMITTED,访问模式为READ ONLY
  2. openGauss=# BEGIN;
  3. openGauss=# DELETE FROM customer_t1 WHERE amount = 1000;
  4. openGauss=# COMMIT;

查询表customer_t1,amount=1000的记录已经被删除。

  1. openGauss=# select * from customer_t1;
  2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
  3. ---------------+---------------+--------------+-------------+--------
  4. 3769 | | Grace | |
  5. 3769 | hello | | |
  6. 6885 | maps | Joes | | 2200
  7. 4321 | tpcds | Lily | | 3000
  8. 9527 | world | James | | 5000
  9. (5 rows)