您的位置:首页 > 数据库 > Oracle

关于Oracle事务的一些实验

2011-04-05 20:36 483 查看
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远程表的操作,这些操作和本地操作效果一样,对于事务来说,都是同进退得。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: