月度归档:2017年05月

MSSQL 如何做行锁(小范围锁)


一、MSSQL锁简介

MSSQL锁种类: 常见锁种类如下四种
1 共享锁 (S) share lock 可以查看数据(阻塞模式为非wait模式),但是不能对数据进行增加、修改和删除操作
2 排它锁 (X) exclusive lock 当一个事务对一个数据加上排它锁后,其它事务不能对此数据加任何锁,但是可以对数据进行任何操作
3 更新锁 (U) update lock 当一个数据被加上更新锁后,其它事务可以对其进行读取操作,但是不能进行修改操作
4 意向锁 () 此锁是数据库引擎自动加上的一种锁,使用意向锁,可以保护数据库的底层资源,防止锁冲突

MSSQL 锁资源范围
根据MSSQL锁资源范围的定义,我们可将锁应用于
RID行锁定
Key 索引范围内锁定
PAG 锁定一页数据
EXT 锁定一个数据簇
TAB 锁定整个数据表
DB 锁定整个数据库
FIL 锁定数据文件


二、如何产生一个小范围提高系统效率

2.1 例一
   2.1.1 建表,并插入数据
    create table [test20170524]
	(keyId int ,
	value varchar(40)
	) 
	go
	insert into [test20170524]
	(keyId,value)
		values
	(1,'a'),
	(2,'b'),
	(3,'C'),
	(4,'d'),
	(5,'e'),
	(6,'f')
	go

    2.1.2 新开一个窗体(挂起一个事务): 
        begin tran 
        update [test20170524] set value='a--' where keyId =1 
      
    2.1.3 新开一个窗体(使用sp_lock查看挂起的事务)
          此时我们可以看出系统,对一定范围内的行,进行了排它锁 
	  
 
    2.1.4 新开一个窗体 查看所有记录
           此时我们发现由于第一个修改使用了排它锁,此时我们所有的查询和插入 修改操作都会处于阻塞等待模式,当"前一个事务"提交后,此事务才会得到运行
        

2.2 例二

    
    2.2.1 建表,并插入数据
    create table [test20170524]
	(keyId int primary key,
	value varchar(40)
	) 
	go
	insert into [test20170524]
	(keyId,value)
		values
	(1,'a'),
	(2,'b'),
	(3,'C'),
	(4,'d'),
	(5,'e'),
	(6,'f')
	go

    2.2.2 新开一个窗体(挂起一个事务): 
        begin tran 
        update [test20170524] set value='a--' where keyId =1 
      
    2.2.3 新开一个窗体(使用sp_lock查看挂起的事务)
          此时我们可以看出系统,对索引范围内的行,进行了排它锁 
	 
 
    2.2.4 新开一个窗体 查看所有记录
           此时我们发现由于第一个修改使用了排它锁,此时我们查询所有记录时,仍然会处于阻塞等待模式,需等待"前一个事务"提交后,此事务才会得到运行
	 
     2.2.5  新开一个窗体 修改非锁定记录的值 
          update [test20170524] set value='b--' where keyId =2 
        此时我们会发现记录可以得到修改   

总结:

在MSSQL,没有单条记录的排它锁,
但是我们可以通过设置主键的方式,将主键作为条件对数据进行修改,此时系统会采用 索引范围内锁定,减少排它锁的范围,增加系统对不同数据的并发性。


相关阅读:
sp_lock 说明
什么情况下 会锁定整张表
检测系统MSSQL中处于事务中的对象
MSSQL如何查看当前进程及被锁表