SET transaction.type = inceptor;
复制
本章介绍事务处理语言。Inceptor支持的事务处理语法包括:
-
BEGIN TRANSACTION:开始事务
-
COMMIT:提交事务
-
ROLLBACK:回滚事务。
模式选择
默认情况下Inceptor会关闭Transaction Mode,要对ORC表进行事务处理,需要通过下面的开关打开ORC表对应的Transaction Mode:
提交和回滚:COMMIT和ROLLBACK
事务处理指令为BEGIN TRANSACTION(开始事务),COMMIT(提交事务)和ROLLBACK(回滚/撤回事务)。一次事务以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。对ORC表的事务提交和回滚有两种方式:
-
手动方式:使用BEGIN TRANSACTION开始一次事务,使用COMMIT提交事务,使用ROLLBACK回滚事务。
语法
BEGIN TRANSACTION <sql_statements> [<sql_statements>] ... COMMIT|ROLLBACK
复制 -
自动提交(默认方式):如果增删改指令(UPDATE, DELETE, MERGE, INSERT)没有以BEGIN TRANSACTION开始,那么Inceptor默认对所有的增删改指令都自动提交,不能回滚。
语法
[BEGIN TRANSACTION] <sql_statement> [COMMIT] [BEGIN TRANSACTION] <sql_statement> [BEGIN TRANSACTION] [COMMIT]
复制这里,用户并不需要输入括号中的事务处理指令,Inceptor 自动执行。
Inceptor支持在事务中执行一个或多个子事务。Inceptor 提供两种执行子事务的方式:嵌套事务(Nested Transaction)和自治事务(Autonomous Transaction)。
嵌套事务
嵌套事务处理就是在一个事务里进行另一个事务。嵌套事务需要写进一个procedure中:
语法
CREATE OR REPLACE PROCEDURE pro_test() IS BEGIN BEGIN TRANSACTION <sql_statement> ... BEGIN TRANSACTION <sql_statement> ... (COMMIT|ROLLBACK) (COMMIT|ROLLBACK) END;
复制
在嵌套事务中,子事务与主事务互相影响。
举例
SET transaction.type=inceptor; TRUNCATE TABLE t111; TRUNCATE TABLE t222; CREATE OR REPLACE PROCEDURE pro_test() IS BEGIN BEGIN TRANSACTION INSERT INTO t111 VALUES ('a', 1) BEGIN TRANSACTION INSERT INTO t222 VALUES ('b', 2) COMMIT ROLLBACK END; BEGIN pro_test() END;
复制
上面的例子中,
BEGIN TRANSACTION INSERT INTO t222 VALUES ('b', 2) COMMIT
复制
为
BEGIN TRANSACTION INSERT INTO t111 VALUES ('a', 1) BEGIN TRANSACTION INSERT INTO t222 VALUES ('b', 2) COMMIT ROLLBACK
复制
的子事务。当Inceptor读到子事务中的COMMIT时,Inceptor会将该COMMIT之前所有的任务提交。也就是说,“向t111插入('a', 1)”和“向t222插入('b',2)”这两条任务都会被提交。主事务中的ROLLBACK和子事务中的COMMIT之间没有任何SQL语句,所以主事务中的ROLLBACK并不回滚任何任务。上面例子执行后,我们查看t111和t222中的记录将会得到下面的结果:
SELECT * FROM t111;
复制
value1 | value2 |
---|---|
a |
1 |
SELECT * FROM t222;
复制
value1 | value2 |
---|---|
b |
2 |
自治事务
自治事务提供一个在主事务中嵌套独立子事务的机制。自治事务从当前事务开始,在其自身的语境中执行。它们能独立地被提交或重新运行,而不影响正在运行的事务,也不被正在运行的事务影响。因为自治事务是与主事务相分离的,所以它不能检测到被修改过的行的当前状态。但是主事务能够检测到已经执行过的自治事务的结果。
要创建一个自治事务,您必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程中执行的SQL语句都是自治的。
语法
-- 定义一个自治事务 CREATE OR REPLACE PROCEDURE transaction_name() IS PRAGMA AUTONOMOUS_TRANSACTION BEGIN <sql_statements> ... COMMIT|ROLLBACK END; -- 使用该自治事务 BEGIN TRANSACTION; <sql_statements>; BEGIN transaction_name() END; COMMIT|ROLLBACK;
复制
我们使用上一节的两个事务举例,将上一节中的事务2定义为自治事务,放在事务1中:
举例
!set plsqlUseSlash true set transaction.type=inceptor; CREATE OR REPLACE PROCEDURE autonomous_insert() IS PRAGMA AUTONOMOUS_TRANSACTION BEGIN --子事务 BEGIN TRANSACTION INSERT INTO t222 VALUES ('b', 2) COMMIT END; / --主事务 BEGIN BEGIN TRANSACTION INSERT INTO t111 VALUES ('a', 1) BEGIN autonomous_insert() END ROLLBACK END; /
复制
在上例中,子事务中的COMMIT将只提交子事务中的任务而不对主事务有任何影响,也就是说该COMMIT只提交“向t2插入('b',2)”这一条任务。而由于主事务以ROLLBACK结束,“向t1插入('a', 1)”这一任务将被回滚。上面例子执行后,我们查看t1和t2中的记录将会得到下面的结果:
SELECT * FROM t111;
复制
value1 | value2 |
---|
SELECT * FROM t222;
复制
value1 | value2 |
---|---|
b |
2 |
设置事务级别
我们提供完整的事务支持能力,用户可以通过 restful 的方式设置数据库的事务级别。
-
SerializableSnapshot,基于快照的可串行化,即 SSI
-
Serializable,基于悲观锁的可串行化
-
RepeatableRead,可以重复读
-
ReadCommitted,读提交
-
ReadUncommitted,读未提交
curl -X GET "<host>:<port>/bulk_transaction_isolation?[pretty]"复制
curl -X PUT "<host>:<port>/bulk_transaction_isolation?level=<isolation_level>&[timeout_s=<timeout>]"复制
管理事务
Inceptor 支持当前锁情况的查询,以及自动分析锁等待链,提供诊断视图的能力。
下面我们提供一个功能演示:
-
第一步:通过两个客户端分别登陆 user1 和 user2 两个用户
-
第二步:在 user1 会话界面,执行下述 SQL 语句:
create table acid_test(a int) stored as holodesk; -- 指定存储格式为 holodesk,当前该存储格式仅社区订阅版或其他商业版产品支持,如需选择其他存储格式,可参考 DDL 建表语句 set transaction.type=holodesk; begin transaction; Batchinsert into acid_test batchvalues( values(1), values(2) ); --不提交事务
复制 -
第三步:检查加锁情况
登录DBA Service 界面,点击【存储-事务】,检查加锁情况
图 10. 可以看到 user1 加锁成功 -
第四步: 在user2 会话界面,执行下述 SQL 语句:
update acid_test set a = a+1 where a = 2; --user2等锁中,等待user1事务提交才能执行成功
复制 -
第五步:检查锁等待链情况 登录 DBA Service 界面,点击存储-事务,查看锁等待情况
图 11. 可以看到 user2 等待 user1 释放锁资源 -
第六步:在 user1 会话界面,提交事务
commit; --user1事务提交成功,释放锁资源。此时user2拿锁并执行成功
复制
此时在 DBA Service 上可以看到,user1、user2 依次提交成功并释放锁资源。