os:windows server 2003 sp2db:db2 v9.5 32bit
在看到DB2隔离级别CS时官方文档(
Isolation levels and performance)有这么一句,
Cursor Stability (CS) locks any row accessed by a transaction of an application while the cursor is positioned on the row. This lock remains in effect until the next row is fetched or the transaction is terminated. However, if any data on a row is changed, the lock must be held until the change is committed to the database.
其中红色部分的意思有点疑问,“if any data on a row is changed”这里的row是当前游标位置的行吗,按照CS隔离级别1)如果是游标当前行会加NS锁,此行是不允许被其它事务update/delete(X锁与NS锁互斥)的。 2)如果不是游标当前行,是结果行中的非游标当前行,那么当游标fetch到此行后,再离开此行,此行的NS锁不会释放直到事务提交吗?
我在v9.5环境下测试发现当游标open后,整个游标所能遍历的范围数据是可以被其它事务所update/delete的,而游标open前,如果在游标遍历范围内有记录被其它事务执行update/delete而没有提交和话则游标无法open,游标会等待NS锁,测试大概是这样的:
Session A:
db2 "create table t(id int ,name varchar(30))"
db2 "insert into t(id,name) values(1,'a'),(2,'b'),(3,'c')"
db2 "commit"
1. 游标打开前执行更新:
Session B:
db2 +c "update t set name='h' where id=2"
Session C:
db2 +c "declare cur_t cursor for select * from t order by id with cs"
db2 +c "open cur_t"
此时Session C处于等待状态
2. 游标打开后执行更新:
执行下面代码前先提交Session B与Session C
Session D:
db2 +c "declare cur_t cursor for select * from t order by id with cs"
db2 +c "open cur_t"
执行Session E代码
db2 +c "fetch cur_t"
可以执行
Session E:
db2 +c "update t set name='x' where id=2"
不会等待,直接执行,再执行Sesion D后续后代码发现对游标fetch也没有问题。
其中锁的监控是通过db2pd -db sample -locks showlock来监控的。
收起