为什么db2频现“锁等待”或“911”错误
大家都知道,多个事务同时更新同一个数据行时必定要发生锁等待。虽然这个是造成锁等待或锁超时的原因,但不是全部。有不少同事在开发过程中发现这样的问题:自己只做一个根据主键update语句,就更新一行,且确知没有别人在更新这行,为什么语句迟迟没反应,想死锁了一样。本人通过几次尝试和试验发现了“秘密”。即db2的严重影响并发性能的地方:
1、无索引,relation scan 锁等待;
2、有索引,update时索引不能并发访问,需“串行”独占访问;
3、锁升级,行锁升级为表锁,阻塞其他事务的行级更新。
试验环境:
db2 v8系列或v9.1.4
db2命令行
主要步骤:
D:/>db2 create table t(id numeric not null,id2 numeric not null,name varchar(10),constraint t_p primary key(id,id2))
DB20000I SQL 命令成功完成。
D:/>db2 insert into t values(1,1,'chennan'),(1,2,'dba'),(1,3,'spsoft'),(2,1,'hubert'),(2,2,'nj_dba'),(2,3,'gdsy')
DB20000I SQL 命令成功完成。
D:/>db2 select * from t
ID ID2 NAME
------- ------- ----------
1. 1. chennan
1. 2. dba
1. 3. spsoft
2. 1. hubert
2. 2. nj_dba
2. 3. gdsy
6 条记录已选择。
开两个db2命令行窗口,模拟两个事务,考虑到最大并发性能,将这两个事务的隔离级别设为UR;且取消“自动提交”选项,以模拟长事务:
db2 => update command options using c off
DB20000I UPDATE COMMAND OPTIONS 命令成功完成。
db2 => set current isolation = ur
DB20000I SQL 命令成功完成。
================================================================
从前面表的定义,看出此表有主键,即在主键上有索引。下面看看这个索引对更新语句的影响:
事务一:
db2 => update t set name='eee' where id=1 and name='chennan'
DB20000I SQL 命令成功完成。
db2 =>
事务二:
db2 => update t set name='fff' where id=1 and name='spsoft'
现象是事务二的语句被阻塞&#
大家都知道,多个事务同时更新同一个数据行时必定要发生锁等待。虽然这个是造成锁等待或锁超时的原因,但不是全部。有不少同事在开发过程中发现这样的问题:自己只做一个根据主键update语句,就更新一行,且确知没有别人在更新这行,为什么语句迟迟没反应,想死锁了一样。本人通过几次尝试和试验发现了“秘密”。即db2的严重影响并发性能的地方:
1、无索引,relation scan 锁等待;
2、有索引,update时索引不能并发访问,需“串行”独占访问;
3、锁升级,行锁升级为表锁,阻塞其他事务的行级更新。
试验环境:
db2 v8系列或v9.1.4
db2命令行
主要步骤:
D:/>db2 create table t(id numeric not null,id2 numeric not null,name varchar(10),constraint t_p primary key(id,id2))
DB20000I SQL 命令成功完成。
D:/>db2 insert into t values(1,1,'chennan'),(1,2,'dba'),(1,3,'spsoft'),(2,1,'hubert'),(2,2,'nj_dba'),(2,3,'gdsy')
DB20000I SQL 命令成功完成。
D:/>db2 select * from t
ID ID2 NAME
------- ------- ----------
1. 1. chennan
1. 2. dba
1. 3. spsoft
2. 1. hubert
2. 2. nj_dba
2. 3. gdsy
6 条记录已选择。
开两个db2命令行窗口,模拟两个事务,考虑到最大并发性能,将这两个事务的隔离级别设为UR;且取消“自动提交”选项,以模拟长事务:
db2 => update command options using c off
DB20000I UPDATE COMMAND OPTIONS 命令成功完成。
db2 => set current isolation = ur
DB20000I SQL 命令成功完成。
================================================================
从前面表的定义,看出此表有主键,即在主键上有索引。下面看看这个索引对更新语句的影响:
事务一:
db2 => update t set name='eee' where id=1 and name='chennan'
DB20000I SQL 命令成功完成。
db2 =>
事务二:
db2 => update t set name='fff' where id=1 and name='spsoft'
现象是事务二的语句被阻塞&#