小议自治事务(六)

这两天看了11gCONCEPT文档的事务部分,发现自治事务还有一些以前没有注意到的地方,这里简单总结一下。

对比自治事务与普通事务的代价差别。

小议自治事务(一):http://yangtingkun.itpub.net/post/468/467765

小议自治事务(二):http://yangtingkun.itpub.net/post/468/467840

小议自治事务(三):http://yangtingkun.itpub.net/post/468/467933

小议自治事务(四):http://yangtingkun.itpub.net/post/468/468031

小议自治事务(五):http://yangtingkun.itpub.net/post/468/468180

 

 

自治事务提供了很方便的事务控制功能,使得用户可以在不影响当前事务的情况下,提交或回滚对数据库的修改。那么Oracle为了实现这个功能是否付出了很多的代价呢,下面对比一下自治事务和普通事务的统计信息:

SQL> CREATE GLOBAL TEMPORARY TABLE T_SESSION_STAT
  2  (ID NUMBER, NAME VARCHAR2(100), VALUE NUMBER)
  3  ON COMMIT PRESERVE ROWS;

表已创建。

SQL> CREATE TABLE T_RECORD (ID NUMBER, NAME VARCHAR2(30));

表已创建。

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3   INSERT INTO T_RECORD VALUES (1, 'TEST');
  4   COMMIT;
  5  END;
  6  /

过程已创建。

SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS
  2   PRAGMA AUTONOMOUS_TRANSACTION;
  3  BEGIN
  4   INSERT INTO T_RECORD VALUES (2, 'TEST');
  5   COMMIT;
  6  END;
  7  /

过程已创建。

SQL> SET SERVEROUT OFF
SQL> BEGIN
  2  
  3   INSERT INTO T_SESSION_STAT SELECT 1, NAME, VALUE
  4   FROM V$SESSTAT A, V$STATNAME B
  5   WHERE A.STATISTIC# = B.STATISTIC#
  6   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
  7  
  8   P_TEST;
  9  
 10   INSERT INTO T_SESSION_STAT SELECT 2, NAME, VALUE
 11   FROM V$SESSTAT A, V$STATNAME B
 12   WHERE A.STATISTIC# = B.STATISTIC#
 13   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 14 
 15   P_TEST_AUTO;
 16  
 17   INSERT INTO T_SESSION_STAT SELECT 3, NAME, VALUE
 18   FROM V$SESSTAT A, V$STATNAME B
 19   WHERE A.STATISTIC# = B.STATISTIC#
 20   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 21 
 22   FOR C IN
 23   (
 24    SELECT *
 25    FROM
 26     (
 27      SELECT A.NAME, C.VALUE + A.VALUE - 2 * B.VALUE VALUE
 28      FROM
 29       T_SESSION_STAT A,
 30       T_SESSION_STAT B,
 31       T_SESSION_STAT C
 32      WHERE A.NAME = B.NAME
 33      AND A.NAME = C.NAME
 34      AND A.ID = 1
 35      AND B.ID = 2
 36      AND C.ID = 3
 37     )
 38    WHERE ABS(VALUE) > 0
 39   ) LOOP
 40    DBMS_OUTPUT.PUT_LINE(RPAD(C.NAME, 50, ' ') || C.VALUE);
 41   END LOOP;
 42  
 43  END;
 44  /

PL/SQL 过程已成功完成。

SQL> TRUNCATE TABLE T_SESSION_STAT;

表被截断。

SQL> SET SERVEROUT ON
SQL> BEGIN
  2  
  3   INSERT INTO T_SESSION_STAT SELECT 1, NAME, VALUE
  4   FROM V$SESSTAT A, V$STATNAME B
  5   WHERE A.STATISTIC# = B.STATISTIC#
  6   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
  7  
  8   P_TEST;
  9  
 10   INSERT INTO T_SESSION_STAT SELECT 2, NAME, VALUE
 11   FROM V$SESSTAT A, V$STATNAME B
 12   WHERE A.STATISTIC# = B.STATISTIC#
 13   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 14 
 15   P_TEST_AUTO;
 16  
 17   INSERT INTO T_SESSION_STAT SELECT 3, NAME, VALUE
 18   FROM V$SESSTAT A, V$STATNAME B
 19   WHERE A.STATISTIC# = B.STATISTIC#
 20   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 21 
 22   FOR C IN
 23   (
 24    SELECT *
 25    FROM
 26     (
 27      SELECT A.NAME, C.VALUE + A.VALUE - 2 * B.VALUE VALUE
 28      FROM
 29       T_SESSION_STAT A,
 30       T_SESSION_STAT B,
 31       T_SESSION_STAT C
 32      WHERE A.NAME = B.NAME
 33      AND A.NAME = C.NAME
 34      AND A.ID = 1
 35      AND B.ID = 2
 36      AND C.ID = 3
 37     )
 38    WHERE ABS(VALUE) > 0
 39   ) LOOP
 40    DBMS_OUTPUT.PUT_LINE(RPAD(C.NAME, 50, ' ') || C.VALUE);
 41   END LOOP;
 42  
 43  END;
 44  /
recursive cpu usage                               2
session logical reads                             6
CPU used by this session                          2
enqueue releases                                  -1
db block gets                                     4
db block gets from cache                          4
consistent gets                                   2
consistent gets from cache                        2
consistent gets - examination                     1
db block changes                                  6
consistent changes                                4
commit cleanout failures: block lost              -2
commit cleanouts                                  -2
calls to kcmgcs                                   1
calls to get snapshot scn: kcmgss                 1
redo size                                         168
undo change vector size                           108
commit txn count during cleanout                  1
IMU commits                                       1
IMU Flushes                                       -1
IMU undo allocation size                          316

PL/SQL 过程已成功完成。

由于第一次调用匿名块和过程会产生会导致递归调用信息,而这些可能干扰统计信息的结果,因此执行两次匿名块,取第二次的结果为最终结果。

从二者的差异可以看到,自治事务产生的redoundo都比普通事务要大一些,这时可以理解的,不过现在只是插入一条记录,不能说明什么问题,关键看这种差异随事务的增大成比例增长还是基本维持原状。

下面修改两个存储过程:

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3   FOR I IN 1..10000 LOOP
  4    INSERT INTO T_RECORD VALUES (1, 'TEST');
  5   END LOOP;
  6   COMMIT;
  7  END;
  8  /

过程已创建。

SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS
  2   PRAGMA AUTONOMOUS_TRANSACTION;
  3  BEGIN
  4   FOR I IN 1..10000 LOOP
  5    INSERT INTO T_RECORD VALUES (2, 'TEST');
  6   END LOOP;
  7   COMMIT;
  8  END;
  9  /

过程已创建。

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

SQL> EXEC P_TEST_AUTO

PL/SQL 过程已成功完成。

SQL> TRUNCATE TABLE T_SESSION_STAT;

表被截断。

SQL> DELETE T_RECORD;

已删除20000行。

SQL> COMMIT;

提交完成。

SQL> BEGIN
  2  
  3   INSERT INTO T_SESSION_STAT SELECT 1, NAME, VALUE
  4   FROM V$SESSTAT A, V$STATNAME B
  5   WHERE A.STATISTIC# = B.STATISTIC#
  6   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
  7  
  8   P_TEST;
  9  
 10   INSERT INTO T_SESSION_STAT SELECT 2, NAME, VALUE
 11   FROM V$SESSTAT A, V$STATNAME B
 12   WHERE A.STATISTIC# = B.STATISTIC#
 13   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 14 
 15   P_TEST_AUTO;
 16  
 17   INSERT INTO T_SESSION_STAT SELECT 3, NAME, VALUE
 18   FROM V$SESSTAT A, V$STATNAME B
 19   WHERE A.STATISTIC# = B.STATISTIC#
 20   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 21 
 22   FOR C IN
 23   (
 24    SELECT *
 25    FROM
 26     (
 27      SELECT A.NAME, C.VALUE + A.VALUE - 2 * B.VALUE VALUE
 28      FROM
 29       T_SESSION_STAT A,
 30       T_SESSION_STAT B,
 31       T_SESSION_STAT C
 32      WHERE A.NAME = B.NAME
 33      AND A.NAME = C.NAME
 34      AND A.ID = 1
 35      AND B.ID = 2
 36      AND C.ID = 3
 37     )
 38    WHERE ABS(VALUE) > 0
 39   ) LOOP
 40    DBMS_OUTPUT.PUT_LINE(RPAD(C.NAME, 50, ' ') || C.VALUE);
 41   END LOOP;
 42  
 43  END;
 44  /
opened cursors cumulative                         -2
recursive calls                                   -32
recursive cpu usage                               5
session logical reads                             -7
CPU used by this session                          1
enqueue requests                                  -2
enqueue releases                                  -3
db block gets                                     -3
db block gets from cache                          -3
consistent gets                                   -4
consistent gets from cache                        -4
consistent gets - examination                     1
db block changes                                  -3
consistent changes                                4
change write time                                 -2
free buffer requested                             -23
commit cleanout failures: block lost              -2
commit cleanouts                                  -1
commit cleanouts successfully completed           1
calls to kcmgcs                                   -5
calls to kcmgas                                   -16
calls to get snapshot scn: kcmgss                 -4
redo entries                                      -84
redo size                                         -2464
redo ordering marks                               -16
undo change vector size                           -104
no work - consistent read gets                    -3
deferred (CURRENT) block cleanout applications    -5
commit txn count during cleanout                  1
active txn count during cleanout                  2
cleanout - number of ktugct calls                 2
IMU undo allocation size                          24648
IMU Redo allocation size                          31200
table scans (short tables)                        -1
table scan rows gotten                            -16
table scan blocks gotten                          -2
cluster key scans                                 -1
cluster key scan block gets                       -1
index fetch by key                                -1
heap block compress                               -7
session cursor cache hits                         -1
buffer is not pinned count                        -1
parse count (total)                               -2
execute count                                     -2

PL/SQL 过程已成功完成。

IMU10gIN MEMORY UNDO的缩写,这个值比较大主要是由于前面进行了DELETE,后面又插入相同的数据,因此Oracle采用了IMU操作。抛去这个因素,其他的差异于事务本身代价相比就小得多了:

SQL> TRUNCATE TABLE T_SESSION_STAT;

表被截断。

SQL> BEGIN
  2  
  3   INSERT INTO T_SESSION_STAT SELECT 1, NAME, VALUE
  4   FROM V$SESSTAT A, V$STATNAME B
  5   WHERE A.STATISTIC# = B.STATISTIC#
  6   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
  7  
  8   P_TEST_AUTO;
  9  
 10   INSERT INTO T_SESSION_STAT SELECT 2, NAME, VALUE
 11   FROM V$SESSTAT A, V$STATNAME B
 12   WHERE A.STATISTIC# = B.STATISTIC#
 13   AND A.SID = (SELECT SID FROM V$MYSTAT WHERE ROWNUM = 1);
 14 
 15   FOR C IN
 16   (
 17    SELECT *
 18    FROM
 19     (
 20      SELECT A.NAME, B.VALUE - A.VALUE VALUE
 21      FROM
 22       T_SESSION_STAT A,
 23       T_SESSION_STAT B
 24      WHERE A.NAME = B.NAME
 25      AND A.ID = 1
 26      AND B.ID = 2
 27     )
 28    WHERE ABS(VALUE) > 1000
 29   ) LOOP
 30    DBMS_OUTPUT.PUT_LINE(RPAD(C.NAME, 50, ' ') || C.VALUE);
 31   END LOOP;
 32  
 33  END;
 34  /
recursive calls                                   10182
session logical reads                             10602
db block gets                                     10492
db block gets from cache                          10492
db block changes                                  20293
redo entries                                      10124
redo size                                         2461664
undo change vector size                           642896
IMU undo allocation size                          12060
IMU Redo allocation size                          15200
execute count                                     10017

PL/SQL 过程已成功完成。

可见,自治事务所带来的额外的代价很小,基本上可以不用过多的考虑。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-420426/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-420426/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值