DB2中三個有關鎖變數DB2_EVALUNCOMMITTED,DB2_SKIPDELETED和DB2_SKIPINSERTED的使用,db2環境變數
本文主要解釋下DB2中三個有關鎖變數DB2_EVALUNCOMMITTED,DB2_SKIPDELETED和DB2_SKIPINSERTED的使用
實驗環境:
DB2 v9.7.0.6
AIX 6.1.0.0
採用預設的隔離等級CS
STUDENT表的DDL與初始內容
CREATE TABLE "E97Q6C "."STUDENT" (
"AGE" INTEGER ,
"NAME" CHAR(8) )
IN "USERSPACE1" ;
$ db2 "select * from student"
AGE NAME
----------- --------
3 xu
5 gao
6 mu
6 mu
6 mu
4 three
1 an
7 record(s) selected.
--分割線--
當啟用DB2_EVALUNCOMMITTED時,DB2可以對未提交的插入(INSERT)或更新(UPDATE)資料進行謂詞判斷。
如果未提交的資料不符合該條語句的謂詞判斷條件,DB2將不對未提交資料加鎖,這樣避免了因為要對
未提交資料加鎖引起的鎖等待狀態,提高了應用程式訪問的並發性。
實驗 1
測試如下(該參數與資料庫配置參數CUR_COMMIT有衝突,因此,測試之前需要先將CUR_COMMIT參數設為disabled.)
首先在session 1裡做一條“未提交的插入(INSERT)操作”
session 1
---------
$ db2 +c "insert into student values(7,'he')"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "select * from student"
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
$ db2 "select * from student where age = 3"
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
可以看到,在session 2裡的兩條語句都因鎖逾時而失敗了。原因是如果使用者在更改(UPDATE)、插入(INSERT)或
刪除(DELETE)一行時,會在這一行加上排它鎖,別的使用者不能讀、寫,除非使用UR隔離等級。
現在啟用DB2_EVALUNCOMMITTED變數,需要重啟執行個體,之後在session 1裡做同樣的插入操作,session 2裡做同樣的查詢
操作:
session 1
------------
$ db2set DB2_EVALUNCOMMITTED=ON
$ db2stop force
$ db2start
$ db2 connect to qsmiao
$ db2 +c "insert into student values(7,'he')"
DB20000I The SQL command completed successfully.
session 2
------------
$ db2 "select * from student"
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
$ db2 "select * from student where age = 3"
AGE NAME
----------- --------
3 xu
1 record(s) selected.
這次可以看到第2條查詢語句是成功的,原因是session 1中有未提交的插入操作,session 2在掃描時,對該行進行了謂詞判斷,發現不符合謂詞盼斷條件
也就是 age = 3 , session 2就不會對該行進行加鎖,因而不會導致鎖逾時。
DB2_SKIPDELETED變數被啟用的效果是:在表訪問期間,會無條件地跳過被刪除的行。
實驗 2:
在預設情況下,即沒有設定DB2_EVALUNCOMMITTED和DB2_SKIPDELETED變數的時候,如果session 1用提交的方式刪除操作的時候,Session 2若要查詢整個表,是要逾時的,
如下:
session 1
---------
$ db2set DB2_SKIPDELETED=OFF
$ db2set DB2_EVALUNCOMMITTED=OFF
$ db2stop force
$ db2start
$ db2 connect to qsmiao
$ db2 +c "delete from student where age=6"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "select * from student"
SQL0911N The current transaction has been rolled back because of a deadlock
or timeout. Reason code "68". SQLSTATE=40001
如下,現在修改DB2_SKIPDELETED為ON,那麼session 2查詢的時候,會無條件地跳過被刪除的行,因此會成功。
session 1
---------
$ db2 rollback
$ db2set DB2_SKIPDELETED=ON
$ db2stop force
$ db2start
$ db2 connect to qsmiao
$ db2 +c "delete from student where age=6"
DB20000I The SQL command completed successfully.
session 2
---------
$ db2 "select * from student"
AGE NAME
----------- --------
3 xu
5 gao
4 three
1 an
4 record(s) selected.
類似的,DB2_SKIPINSERTED變數的作用是無條件地跳過被插入的行,就像它們還沒有被插入。
參考資料:
牛新莊 《進階進階DB2(第2版)》
db2 我想對一個可以為null的變數賦值null 怎做?
這樣是不可以的,正確的用法如下:
insert into test values(123, null)
或者
insert into test(a) values(123)
如果b沒有default值,上面兩句執行之後b的值都是null。
db2 聲明變數問題,教下
把所有變數聲明都放在開頭,如:
CREATE PROCEDURE "AML"."CZJY053"
(IN "DATADATE" VARCHAR(8)
)
BEGIN
declare period varchar(20);--回顧周期
declare times varchar(20);--周期內發生次數
declare sum_crat varchar(20);--周期內金額總額
set period = (select value from CONTEXT_VARIABLE where type = 'CZJY053' and key = 'period');
set times = (select value from CONTEXT_VARIABLE where type = 'CZJY053' and key = 'times');
set sum_crat = (select value from CONTEXT_VARIABLE where type = 'CZJY053' and key = 'sum_crat');
DELETE FROM T_FXQNBS WHERE REMARK1 = 'CZJY053';
INSERT INTO T_FXQNBS select * FROM FXQTRADE_CC TRANS,(SELECT CSNM,TCAC FROM FXQTRADE_CC WHERE TSTM>to_char(to_date(DATADATE,'yyyymmdd')-period days,'yyyymmdd') AND opcustomtype in (select key_value from FXQPARAM where key ='opcustomtype_cc') GROUP BY CSNM,TCAC HAVING COUNT(*)>=9 AND SUM(CRAT) >=1800000) A
WHERE TRANS.TSTM = DATADATE
AND TRANS.CSNM = A.CSNM
AND TRANS.TCAC = A.TCAC;
END;