1、sql文
begin tran
update table4 with(rowlock,holdlock) set [name] = 'aaaaaaaaaa' where [id] = '1' and id1 = '1'
waitfor delay '00:00:30' --等待30秒
commit tran
2、数据库重的数据
id(key1) id1(key2) name
1 1 a
1 2 b
2 1 c
2 2 d
执行这个sql文后,对数据库按单一健值进行检索的时候,都被锁定,需要等待事务提交之后才能够执行
但是全健值检索的时候,能够进行检索。
请问如何降低锁定粒度,可以按单一健值进行检索。
---------------------------------------------------------------
--查询分析器
/==== A窗口写如下语句 ==/
--测试表
create table tb(id int,id1 int,name varchar(10),primary key(id,id1))
insert tb select 1,1,'a'
union all select 1,2,'b'
union all select 2,1,'c'
union all select 2,2,'d'
go
--处理语句
begin tran
update tb with(rowlock) set name='aa' where id=1 and id1=1
waitfor delay '00:00:30' --等待30秒
commit tran
go
--删除测试
drop table tb
/==== B窗口写如下语句 ==/
select * from tb where id=1
/==== C窗口写如下语句 ==/
select * from tb where id=2
按顺序执行A,B,C三个窗口的语句,你会发现B窗口被锁定,C窗口的语句没有被锁定
---------------------------------------------------------------
--把测试改为
/==== A窗口写如下语句 ==/
--测试表
create table tb(id int,id1 int,name varchar(10),primary key(id,id1))
insert tb select 1,1,'a'
union all select 1,2,'b'
union all select 2,1,'c'
union all select 2,2,'d'
go
--处理语句
begin tran
update tb with(rowlock) set name='aa' where id=1 and id1=1
waitfor delay '00:00:30' --等待30秒
commit tran
go
--删除测试
drop table tb
/==== B窗口写如下语句 ==/
select * from tb where id1=1
/==== C窗口写如下语句 ==/
select * from tb where id1=2
按顺序执行A,B,C三个窗口的语句,你会发现B,C窗口均被锁定,看来跟主键中设置的字段顺序有关
推论:
由于索引是按索引字段顺序存放索引信息,所以用了锁后,在主字段(第1字段)上查询能够确定锁的位置(是否被锁定),而在辅字段上查询,由于定位问题,所以导致无法判断记录是否被锁,这样就造成在辅助字段上查询即被锁
解决的办法,建立多一个唯一索引,看下面的测试
--把测试改为
/==== A窗口写如下语句 ==/
--测试表
create table tb(id int,id1 int,name varchar(10),primary key(id,id1),unique(id1,id))
insert tb select 1,1,'a'
union all select 1,2,'b'
union all select 2,1,'c'
union all select 2,2,'d'
go
--处理语句
begin tran
update tb with(rowlock) set name='aa' where id=1 and id1=1
waitfor delay '00:00:30' --等待30秒
commit tran
go
--删除测试
drop table tb
/==== B窗口写如下语句 ==/
select * from tb where id1=1
/==== C窗口写如下语句 ==/
select * from tb where id1=2
按顺序执行A,B,C三个窗口的语句,你会发现B窗口被锁定,C窗口的语句没有被锁定