首页 / 新闻

11.

17

2015

星环科技攻克分布式数据库难点—分布式事务处理

技术博客

分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。分布式事务处理一直都是分布式数据库中的难题。星环科技的Inceptor实现了对ORC表的分布式事务处理。


模式选择


默认情况下Inceptor关闭Transaction Mode,要对ORC表进行事务处理,需要通过下面的开关 打开ORC表对应的Transaction Mode:
SET transaction.type = inceptor;


1.1. 事务的提交和回滚


事务处理指令为BEGIN TRANSACTION(开始事务),COMMIT(提交事务)和ROLLBACK(回滚/撤 回事务)。对ORC表的事务提交和回滚有两种方式:
• 手动方式:使用BEGIN TRANSACTION开始一次事务,使用COMMIT提交事务,使用ROLLBACK回 滚事务。


语法


BEGIN TRANSACTION

sql_statements

sql_statements
...

COMMIT|ROLLBACK
• 自动提交(默认方式):不使用事务处理指令。Inceptor默认对所有的增删改指令都自动 提交。


语法


(BEGIN TRANSACTION)

sql_statement

(COMMIT)

(BEGIN TRANSACTION)
sql_statement

(COMMIT)
(BEGIN TRANSACTION)
...

这里,用户并不需要输入括号中的事务处理指令。Inceptor会自动执行。 Inceptor支持在事务中执行一个或多个子事务。Inceptor提供两种执行子事务的方式:

嵌套事务(Nested Transaction)和自治事务(Autonomous Transaction)。


1. 嵌套事务

嵌套事务处理就是在一个事务里进行另一个事务。嵌套事务需要写进一个procedure中:

 

语法


create or replace procedure pro_test() is begin
BEGIN TRANSACTION
sql_statement
...
BEGIN TRANSACTION
sql_statement
...

(COMMIT|ROLLBACK)

(COMMIT|ROLLBACK)

end;
在嵌套事务中,子事务与主事务互相影响。


举例


[$host] transwarp> SET transaction.type=inceptor; [host] transwarp> TRUNCATE TABLE t2;
[$host] transwarp> create or replace procedure pro_test() is begin
BEGIN TRANSACTION
INSERT INTO t1 VALUES ('a', 1)

BEGIN TRANSACTION
INSERT INTO t2 VALUES ('b', 2)

COMMIT
ROLLBACK
end;

[$host] transwarp> begin

pro_test()

end;

 

上面的例子中,事务2


BEGIN TRANSACTION
INSERT INTO t2 VALUES ('b', 2)

COMMIT
为事务1
BEGIN TRANSACTION
INSERT INTO t1 VALUES ('a', 1) ROLLBACK
的子事务。当Inceptor读到事务2中的COMMIT时,Inceptor会将该COMMIT之前所有的任务提 交。也就是说,“向t1插入('a', 1)”和“向t2插入('b',2)”这两条任务都会被提交。事务1中的ROLLBACK和事务2中的COMMIT之间没有任何SQL语句,所以事务1中 的ROLLBACK并不回滚任 何任务。上面例子执行后,我们查看t1和t2中的记录将会得到下面的结果:
[$host] transwarp> SELECT * FROM t1;
'a', 1
[$host] transwarp> SELECT * FROM t2;
'b', 2


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中:

 

举例

 

CREATE OR REPLACE PROCEDURE autonomous_insert() IS PRAGMA AUTONOMOUS_TRANSACTION
BEGIN
//子事务
BEGIN TRANSACTION
INSERT INTO t2 VALUES ('b', 2)

COMMIT
END
;
//主事务
BEGIN TRANSACTION;
INSERT INTO t1 VALUES ('a', 1);
autonomous_insert();

ROLLBACK;


在上例中,子事务中的COMMIT将只提交子事务中的任务而不对主事务有任何影响,也就是说该COMMIT只提交“向t2插入('b',2)”这一条任务。而由于主事务以ROLLBACK结束,“向t1插入 ('a', 1)”这一任务将被回滚。上面例子执行后,我们查看t1和t2中的记录将会得到下面的结果:
[host] transwarp> SELECT * from t2;
'b', 2