关于Oracle事务的一些实验

Oracle数据库环境设置:

1、数据库A 服务名L25steel。 A中建立两个表 testtransaction、testransaction2 。两个表表结构相同:只包含一列cid,该列为主键。

在A中建立访问数据库B的dblink,命名为dblinktest

2、数据库B 服务名dblinktest。B中建立一个表testtransaction。表结构同A中的表结构

 

实验主要操作是同时在两个表中插入同样的数据。

首先我们不考虑dblink远程访问,先在数据库A的两个表中插入数据。

  • 实验一 对A库中的两个表执行两个操作,事务中不捕获、处理异常

实验前首先确保:A中表testtransaction记录为空,testtransaction2包含一条记录‘1’

在sqlplus命令行中下面语句:

SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 
SQL> select * from testtransaction2;
 
CID
--------------------------------------------------
1
 
SQL>
SQL> BEGIN
  2   insert into testtransaction(cid) values('1');
  3   insert into   testtransaction2  (cid) values('1');
  4  END;
  5  /
 
BEGIN
 insert into testtransaction(cid) values('1');
 insert into   testtransaction2  (cid) values('1');
END;
 
ORA-00001: 违反唯一约束条件 (LEVEL25.TTPK2)
ORA-06512: 在 line 4
 
SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 

 

 从上面的操作,我们可以看到,begin end之间的语句作为同一个事务,同进同退,第二条语句没有执行成功,那么一条语句即使成功了也会回滚回去。所以在同一个回话中也查不到testtransaction中有记录。

 

  • 实验二 在同一库中操作两个表,并设置异常处理

实验前首先确保:A中表testtransaction记录为空,testtransaction2包含一条记录‘1’

在sqlplus命令行中下面语句:

SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 
SQL> select * from testtransaction2;
 
CID
--------------------------------------------------
1
 
SQL>
SQL> BEGIN
  2   insert into testtransaction(cid) values('1');
  3   insert into   testtransaction2  (cid) values('1');
  4   exception when others then
  5   dbms_output.put_line('error');
  6  END;
  7  /
 
PL/SQL procedure successfully completed
 

 

然后紧接着执行查询语句


SQL> select * from testtransaction;

 

结果会是什么呢?????

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


结果:

 
CID
--------------------------------------------------
1

 

实验二所执行的事务 begin end 之间的部分,比实验一多了一句异常处理

4   exception when others then

  5   dbms_output.put_line('error');

这句表示,遇到异常的默认处理方式就是输出一个“error”;

执行此事务后,我们再查询testransaction表,里面居然有了一条记录‘1’;

怎么回事?我们本希望这两句同进同退的啊!

原来恰恰是这个异常处理惹的祸。如果在一个事务处理中加了异常处理,那么oracle认为,如果事务的某个操作出了异常(必须是异常处理能捕获的异常),由用户(程序员)来解决如何处理。这时候如果用户代码捕获了异常什么都不做,那么oracle认为用户表示“出了异常也无所谓”,那么oracle就会把当前事务作为一个成功执行的结果,而不会擅自做回滚了。

所以,在这里如果用户认为插入两个表的操作应该同进同退,如果一个没插入成功,其他的操作也回滚的话,正确处理应该是

SQL> BEGIN
  2   insert into testtransaction(cid) values('1');
  3   insert into   testtransaction2  (cid) values('1');
  4   exception when others then
  5   rollback;
  6   dbms_output.put_line('error');
  7  END;
  8  /

 

或者不要做异常处理(两个操作会同进退,但如果有异常,异常会被抛出到命令行或者程序中)。所以说,鲁莽的异常出来还不如不做处理。

 

实验三 事务中分别操作本地表和远程表(dblink方式),不处理异常

实验前首先确保:A中表testtransaction记录为空,B库表testtransaction包含一条记录‘1’

在sqlplus命令行中下面语句:

 

 

 

SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 
SQL> select * from testtransaction@dblinktest;
 
CID
--------------------------------------------------
1
 
SQL>
SQL> BEGIN
  2   insert into testtransaction(cid) values('1');
  3   insert into   testtransaction@dblinktest  (cid) values('1');
  4  END;
  5  /
 
BEGIN
 insert into testtransaction(cid) values('1');
 insert into   testtransaction@dblinktest  (cid) values('1');
END;
 
ORA-00001: 违反唯一约束条件 (LEVEL25.TTPK)
ORA-02063: 紧接着 line (起自 DBLINKTEST)
ORA-06512: 在 line 4
 
SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 

 

在这个实验中我们看到,事务操作了两个表,本地表和远程表。如果在执行远程表时发生异常,那么本地表的执行也会被回滚。

 

 

 

实验四 事务中分别操作本地表和远程表(dblink方式),捕获异常

 

实验前首先确保:A中表testtransaction记录为空,B库表testtransaction包含一条记录‘1’

在sqlplus命令行中下面语句:

 

 

SQL> select * from testtransaction;
 
CID
--------------------------------------------------
 
SQL> select * from testtransaction@dblinktest;
 
CID
--------------------------------------------------
1
 
SQL>
SQL> BEGIN
  2   insert into testtransaction(cid) values('1');
  3   insert into   testtransaction@dblinktest  (cid) values('1');
  4   exception when others then
  5   dbms_output.put_line('error');
  6  END;
  7  /
 
PL/SQL procedure successfully completed
 
SQL> select * from testtransaction;
 
CID
--------------------------------------------------
1

 

 

在这个实验中我们可以看到,和实验二结果相同,由于用户给了异常处理,oracle没有回滚本地操作,从而能在本地表中查到数据。

 

 

通过这四个实验得出这样两条结论:

1、用户在事务处理中设置了异常处理,则即使发生了用户能捕获的异常,oracle也不会对成功的操作做回滚,而交由用户来处理。

2、事务中包含对dblink远程表的操作,这些操作和本地操作效果一样,对于事务来说,都是同进退得。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值