Oracle 事务相关的一些测试
1.sqlplus 客户端正常退出
SQL> desc t; 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- TSP TIMESTAMP(6) CNT NOT NULL NUMBER(38) SQL> insert into t values(sysdate,1); 已创建 1 行。 SQL> exit 从 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 断开 C:\Users\zen>sqlplus hbkf_crm/hbkf_crm4test SQL*Plus: Release 11.2.0.1.0 Production on 星期日 11月 17 12:28:29 2013 Copyright (c) 1982, 2010, Oracle. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> select * from t; TSP --------------------------------------------------------------------------- CNT ---------- 17-11月-13 12.27.58.000000 下午 1 SQL>
语句正常执行sqlplus正常退出,sqlplus commit修改。
SQL> insert into t values(sysdate,2); 已创建 1 行。 SQL> insert into t values(sysdate,2); insert into t values(sysdate,2) * 第 1 行出现错误: ORA-00001: 违反唯一约束条件 (HBKF_CRM.SYS_C0011518) SQL> exit 从 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 断开 C:\Users\zen>sqlplus hbkf_crm/hbkf_crm4test SQL*Plus: Release 11.2.0.1.0 Production on 星期日 11月 17 12:33:35 2013 Copyright (c) 1982, 2010, Oracle. All rights reserved. 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> select * from t; TSP --------------------------------------------------------------------------- CNT ---------- 17-11月-13 12.27.58.000000 下午 1 17-11月-13 12.33.19.000000 下午 2 SQL>
这里应该是显示的语句级原子性。
SQL> select name,text from user_source t where t.name ='P1'; NAME TEXT ----- ------------------------------------------------------------ P1 procedure p1(num INT) P1 IS P1 P1 BEGIN P1 P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+1); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 COMMIT; P1 NAME TEXT ----- ------------------------------------------------------------ P1 end p1; 已选择12行。 SQL> exec p1(6); BEGIN p1(6); END; * 第 1 行出现错误: ORA-00001: 违反唯一约束条件 (HBKF_CRM.SYS_C0011518) ORA-06512: 在 "HBKF_CRM.P1", line 9 ORA-06512: 在 line 1 SQL> select * from t; TSP ------------------------------------------------------------------------- CNT ---------- 17-11月-13 12.27.58.000000 下午 1 17-11月-13 12.49.08.000000 下午 3 17-11月-13 12.33.19.000000 下午 2 TSP ------------------------------------------------------------------------- CNT ---------- 17-11月-13 12.46.55.000000 下午 4 17-11月-13 12.47.23.000000 下午 5 SQL> select name,text from user_source t where t.name ='P1'; NAME TEXT ----- ------------------------------------------------------------ P1 procedure p1(num INT) P1 IS P1 P1 BEGIN P1 P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+1); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 COMMIT; P1 EXCEPTION WHEN OTHERS THEN NAME TEXT ----- ------------------------------------------------------------ P1 dbms_output.put_line(sqlcode||':'||SQLERRM); P1 P1 end p1; 已选择14行。 SQL> exec p1(6); PL/SQL 过程已成功完成。
SQL> select tsp,cnt from t; TSP CNT ---------------------------------- ---------- 17-11月-13 01.00.20.000000 下午 6 17-11月-13 01.00.20.000000 下午 7 17-11月-13 01.00.20.000000 下午 8 17-11月-13 12.27.58.000000 下午 1 17-11月-13 12.49.08.000000 下午 3 17-11月-13 12.33.19.000000 下午 2 17-11月-13 12.46.55.000000 下午 4 17-11月-13 12.47.23.000000 下午 5 已选择8行。 SQL>
可以看出TOM大师为何对 when others 语句如此有看法了SQL> select name,text from user_source t where t.name ='P1';
NAME TEXT ----- ------------------------------------------------------------ P1 procedure p1(num INT) P1 IS P1 P1 BEGIN P1 P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+1); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 COMMIT; P1 EXCEPTION WHEN OTHERS THEN NAME TEXT ----- ------------------------------------------------------------ P1 dbms_output.put_line(sqlcode||':'||SQLERRM); P1 ROLLBACK; P1 end p1; 已选择14行。 SQL> exec p1(10); PL/SQL 过程已成功完成。 SQL> select * from t; TSP CNT ---------------------------------- ---------- 17-11月-13 12.27.58.000000 下午 1 17-11月-13 12.49.08.000000 下午 3 17-11月-13 12.33.19.000000 下午 2 17-11月-13 12.46.55.000000 下午 4 17-11月-13 12.47.23.000000 下午 5
--加上rollback 可以回滚整个事务。
SQL> select name,text from user_source t where t.name ='P1'; NAME TEXT ----- ------------------------------------------------------------ P1 procedure p1(num INT) P1 IS P1 P1 BEGIN P1 P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+1); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 INSERT INTO t(tsp,cnt) VALUES(sysdate,num+2); P1 COMMIT; P1 EXCEPTION WHEN OTHERS THEN NAME TEXT ----- ------------------------------------------------------------ P1 dbms_output.put_line(sqlcode||':'||SQLERRM); P1 --ROLLBACK; P1 RAISE; P1 end p1; 已选择15行。
SQL> exec p1(10); BEGIN p1(10); END; * 第 1 行出现错误: ORA-00001: 违反唯一约束条件 (HBKF_CRM.SYS_C0011518) ORA-06512: 在 "HBKF_CRM.P1", line 14 ORA-06512: 在 line 1 SQL> select * from t; TSP CNT ---------------------------------- ---------- 17-11月-13 12.27.58.000000 下午 1 17-11月-13 12.49.08.000000 下午 3 17-11月-13 12.33.19.000000 下午 2 17-11月-13 12.46.55.000000 下午 4 17-11月-13 12.47.23.000000 下午 5
--抛出异常也会使事务回滚。
一个好的习惯是捕获到了错误,要么回滚,要么抛出异常。