BEGIN¶
说明¶
开始一个事务
参数¶
WORK
表示开始一个事务。此参数没有意义。
TRANSACTION
表示开始一个事务。此参数没有意义。
READ ONLY
表示开始的事务只读。
READ WRITE
表示开始的事务可读写。
注解
如果当前已经在一个事务中了,语句 BEGIN; 将导致出错。
当没有申明 READ ONLY 和 READ WRITE 时,在不同的情况下采取不同的默认值:当数据库只读、或当前 session 只读、或当前 session 的隔离级别为 READ UNCOMMITTED 时,开始的事务将是只读的。否则开始的时候就是可读写的。
如果数据库只读、或当前session 只读、或当前 session 的隔离级别为 READ UNCOMMITTED 时,申明 READ WRITE 则导致出错,开始事务失败。
当开始一个事务之后,执行其他语句之前,可以使用 SET TRANSACTION 语句设置事务的读写属性和隔离级别。一旦执行过其他 DML 或 DDL 语句,表示事务被激活,再次使用 SET TRANSACTION 设置事务属性将失败。
当 AUTOCOMMIT 配置参数为 FALSE 时,执行一条 DML 或 DDL 或 SET TRANSACTION 语句之后,将自动进入一个事务。这相当于在这条语句之前输入了一条 BEGIN; 语句。参见 SET AUTOCOMMIT 。
若DDLCOMMITBEHAVIOR配置参数为0,且当前位于显性事务中,DDL语句执行将会自动提交先前事务,通过单独事务完成DDL操作,并最后自动开启新的事务。即显性事务中DDL操作分三个过程:COMMIT、DDL、BEGIN,且最终事务不继承原有事务的属性。
当开始只读事务时,事务将不能对数据库产生写操作,否则就出错。但若DDL自动提交功能开启,内部新开的独立事务可以成功执行,即用户的只读事务可以发生写操作。 参见下文示例2、示例3。
示例¶
示例1: 开始一个事务
-- 清理环境
DROP TABLE tab1 CASCADE;
-- 创建表并插入数据
CREATE TABLE tab1 (a INT);
INSERT INTO tab1 VALUES(1);
INSERT INTO tab1 VALUES(2);
SELECT * FROM tab1 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
总数目:2
-- 开始一个事务
BEGIN;
-- 事务中插入一条数据
INSERT INTO tab1 VALUES(3);
SELECT * FROM tab1 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
------------
3 |
总数目:3
-- 回滚事务, 事务中插入的数据不存在了
ROLLBACK;
SELECT * FROM tab1 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
总数目:2
-- 删除表
DROP TABLE tab1;
示例2: 开始一个只读事务, 执行写数据操作
-- 清理环境
DROP TABLE tab2 CASCADE;
-- 创建表并插入数据
CREATE TABLE tab2 (a INT);
INSERT INTO tab2 VALUES(1);
INSERT INTO tab2 VALUES(2);
SELECT * FROM tab2 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
总数目:2
-- 开始一个只读事务
BEGIN READ ONLY;
-- 只读事务中插入数据失败
INSERT INTO tab2 VALUES(3);
ERROR, 事务只读,该语句出错(INSERT INTO tab2 VALUES(3))
SELECT * FROM tab2 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
总数目:2
-- 提交事务(结束事务)
COMMIT;
-- 删除表
DROP TABLE tab2;
示例3: 开始一个只读事务, 执行 DDL 操作
-- 清理环境
DROP TABLE tab3 CASCADE;
-- 设置 DDL 自动提交
set DDLCOMMITBEHAVIOR = 0;
-- 表 tab3 不存在, 查询报错
SELECT * FROM tab3;
ERROR, Relation "TAB3" does not exist
-- 开始一个只读事务
BEGIN READ ONLY;
-- 执行 DDL 语句
CREATE TABLE tab3 (a INT);
-- DDL 自动提交, 可以执行写数据操作了
INSERT INTO tab3 VALUES(1);
SELECT * FROM tab3 ORDER BY a;
A(int) |
------------
1 |
总数目:1
-- 回滚事务
ROLLBACK;
-- 由于设置 DDL 自动提交
-- 导致 tab3 表已存在, 回滚后没有数据
SELECT * FROM tab3 ORDER BY a;
A(int) |
总数目:0
-- 删除表
DROP TABLE tab3;
-- 设置 DDL 非自动提交
set DDLCOMMITBEHAVIOR = 1;
-- 表 tab3 不存在, 查询报错
SELECT * FROM tab3;
ERROR, Relation "TAB3" does not exist
-- 开始一个只读事务
BEGIN READ ONLY;
-- 执行 DDL 语句
CREATE TABLE tab3 (a INT);
ERROR, 事务只读,该语句出错(CREATE TABLE tab3 (a INT))
SELECT * FROM tab3 ORDER BY a;
ERROR, Relation "TAB3" does not exist
-- 回滚事务
ROLLBACK;
-- 由于设置 DDL 非自动提交
-- 导致回滚后 tab3 表不存在, 查询报错
SELECT * FROM tab3 ORDER BY a;
ERROR, Relation "TAB3" does not exist
-- 重置参数
reset DDLCOMMITBEHAVIOR;
示例4: 开始事务之后设置其属性
-- 清理环境
DROP TABLE tab4 CASCADE;
-- 创建表并插入数据
CREATE TABLE tab4 (a INT);
INSERT INTO tab4 VALUES(1);
INSERT INTO tab4 VALUES(2);
SELECT * FROM tab4 ORDER BY a;
A(int) |
------------
1 |
------------
2 |
总数目:2
-- 开始一个事务
BEGIN;
-- 设置该事务只读
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 只读事务中插入数据失败
INSERT INTO tab4 VALUES(3);
ERROR, 事务只读,该语句出错(INSERT INTO tab4 VALUES(3))
-- 回滚事务
ROLLBACK;
-- 删除表
DROP TABLE tab4;