1 如何锁一个表的某一行

一. 锁使用注意事项
如何避免死锁
澳门新葡萄京官网首页,1 使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;
3 设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;
3 所有的SP都要有错误处理(通过@@error)
4 一般不要修改SQL
SERVER事务的默认级别。不推荐强行加锁
二. 几个有关加锁的例子

行锁的基本说明:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

澳门新葡萄京官网首页 1澳门新葡萄京官网首页 2代码

SELECT au_lname FROM authors WITH (NOLOCK)

SELECT * FROM table ROWLOCK WHERE id = 1

1 如何锁一个表的某一行 
SELECT * FROM table ROWLOCK WHERE id = 1 

锁定提示                                 描述  
HOLDLOCK       
将共享锁保留到事务完成,而不是在相应的表、行或数据页不再需要时就立即释放锁。HOLDLOCK       
等同于        SERIALIZABLE。        
NOLOCK       
不要发出共享锁,并且不要提供排它锁。当此选项生效时,可能会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于        SELECT       
语句。        
PAGLOCK        在通常使用单个表锁的地方采用页锁。        
READCOMMITTED       
用与运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下,SQL       
Server        2000       
在此隔离级别上操作。        
READPAST       
跳过锁定行。此选项导致事务跳过由其它事务锁定的行(这些行平常会显示在结果集内),而不是阻塞该事务,使其等待其它事务释放在这些行上的锁。READPAST       
锁提示仅适用于运行在提交读隔离级别的事务,并且只在行级锁之后读取。仅适用于        SELECT       
语句。        
READUNCOMMITTED        等同于        NOLOCK。        
REPEATABLEREAD       
用与运行在可重复读隔离级别的事务相同的锁语义执行扫描。        
ROWLOCK        使用行级锁,而不使用粒度更粗的页级锁和表级锁。        
SERIALIZABLE       
用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于        HOLDLOCK。        
TABLOCK       
使用表锁代替粒度更细的行级锁或页级锁。在语句结束前,SQL       
Server        一直持有该锁。但是,如果同时指定        HOLDLOCK,那么在事务结束之前,锁将被一直持有。        
TABLOCKX       
使用表的排它锁。该锁可以防止其它事务读取或更新表,并在语句或事务结束前一直持有。        
UPDLOCK       
读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK       
的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。        
XLOCK       
使用排它锁并一直保持到由语句处理的所有数据上的事务结束时。可以使用       
PAGLOCK        或        TABLOCK       
指定该锁,这种情况下排它锁适用于适当级别的粒度

2 锁定数据库的一个表

2 锁定数据库的一个表 
SELECT * FROM table WITH (HOLDLOCK) 

 

SELECT * FROM table WITH (HOLDLOCK)

加锁语句:
sybase:
update 表 set col1=col1 where 1=0 ;
MSSQL:
select col1 from 表 (tablockx) where 1=0 ;
oracle:
LOCK TABLE 表 IN EXCLUSIVE MODE ;
加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁 

1 如何锁一个表的某一行  

加锁语句:
sybase:
update 表 set col1=col1 where 1=0 ;
MSSQL:
select col1 from 表 (tablockx) where 1=0 ;
oracle:
LOCK TABLE 表 IN EXCLUSIVE MODE ;
加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁

几个例子帮助大家加深印象
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3 

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED  

几个例子帮助大家加深印象
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c3

1)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A=’aa’
where B=’b2′
waitfor delay ’00:00:30′ –等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B=’b2′ 
commit tran 

SELECT * FROM table ROWLOCK WHERE id = 1  

1)排它锁
新建两个连接
在第一个连接中执行以下语句
begin tran
update table1
set A=’aa’
where B=’b2′
waitfor delay ’00:00:30′ –等待30秒
commit tran
在第二个连接中执行以下语句
begin tran
select * from table1
where B=’b2′
commit tran

若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒 

2 锁定数据库的一个表  

若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒

2)共享锁
在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B=’b2′ 
waitfor delay ’00:00:30′ –等待30秒
commit tran 

SELECT * FROM table WITH (HOLDLOCK)  

2)共享锁
在第一个连接中执行以下语句
begin tran
select * from table1 holdlock -holdlock人为加锁
where B=’b2′
waitfor delay ’00:00:30′ –等待30秒
commit tran

在第二个连接中执行以下语句
begin tran
select A,C from table1
where B=’b2′ 
update table1
set A=’aa’
where B=’b2′ 
commit tran 

加锁语句: 
sybase: 
update 表 set col1=col1 where 1=0 ; 
MSSQL: 
select col1 from 表 (tablockx) where 1=0 ; 
oracle: 
LOCK TABLE 表 IN EXCLUSIVE MODE ; 
加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁  

在第二个连接中执行以下语句
begin tran
select A,C from table1
where B=’b2′
update table1
set A=’aa’
where B=’b2′
commit tran

若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个事务释放共享锁转为排它锁后才能执行 即要等待30秒 

几个例子帮助大家加深印象 
设table1(A,B,C) 
A B C 
a1 b1 c1 
a2 b2 c2 
a3 b3 c3  

若同时执行上述两个语句,则第二个连接中的select查询可以执行
而update必须等待第一个事务释放共享锁转为排它锁后才能执行 即要等待30秒

3)死锁
增设table2(D,E)
D E
d1 e1
d2 e2
在第一个连接中执行以下语句
begin tran
update table1
set A=’aa’
where B=’b2′ 
waitfor delay ’00:00:30′
update table2
set D=’d5′
where E=’e1′ 
commit tran

1)排它锁 
新建两个连接 
在第一个连接中执行以下语句 
begin tran 
update table1 
set A=’aa’ 
where B=’b2′ 
waitfor delay ’00:00:30′ –等待30秒 
commit tran 
在第二个连接中执行以下语句 
begin tran 
select * from table1 
where B=’b2′  
commit tran  

3)死锁
增设table2(D,E)
D E
d1 e1
d2 e2
在第一个连接中执行以下语句
begin tran
update table1
set A=’aa’
where B=’b2′
waitfor delay ’00:00:30′
update table2
set D=’d5′
where E=’e1′
commit tran

在第二个连接中执行以下语句
begin tran
update table2
set D=’d5′
where E=’e1′ 
waitfor delay ’00:00:10′
update table1
set A=’aa’
where B=’b2′ 
commit tran 

若同时执行上述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒  

在第二个连接中执行以下语句
begin tran
update table2
set D=’d5′
where E=’e1′
waitfor delay ’00:00:10′
update table1
set A=’aa’
where B=’b2′
commit tran

同时执行,系统会检测出死锁,并中止进程 

2)共享锁 
在第一个连接中执行以下语句 
begin tran 
select * from table1 holdlock -holdlock人为加锁 
where B=’b2′  
waitfor delay ’00:00:30′ –等待30秒 
commit tran  

补充一点:
Sql Server2000支持的表级锁定提示 

在第二个连接中执行以下语句 
begin tran 
select A,C from table1 
where B=’b2′  
update table1 
set A=’aa’ 
where B=’b2′  
commit tran  

HOLDLOCK 持有共享锁,直到整个事务完成,应该在被锁对象不需要时立即释放,等于SERIALIZABLE事务隔离级别 

若同时执行上述两个语句,则第二个连接中的select查询可以执行 
而update必须等待第一个事务释放共享锁转为排它锁后才能执行
即要等待30秒  

NOLOCK 语句执行时不发出共享锁,允许脏读 ,等于 READ UNCOMMITTED事务隔离级别 

3)死锁 
增设table2(D,E) 
D E 
d1 e1 
d2 e2 
在第一个连接中执行以下语句 
begin tran 
update table1 
set A=’aa’ 
where B=’b2′  
waitfor delay ’00:00:30′ 
update table2 
set D=’d5′ 
where E=’e1′  
commit tran 

PAGLOCK 在使用一个表锁的地方用多个页锁 

在第二个连接中执行以下语句 
begin tran 
update table2 
set D=’d5′ 
where E=’e1′  
waitfor delay ’00:00:10′ 
update table1 
set A=’aa’

READPAST 让sql server跳过任何锁定行,执行事务,适用于READ UNCOMMITTED事务隔离级别只跳过RID锁,不跳过页,区域和表锁 

ROWLOCK 强制使用行锁 

TABLOCKX 强制使用独占表级锁,这个锁在事务期间阻止任何其他事务使用这个表 

UPLOCK 强制在读表时使用更新而不用共享锁 

 

三. 查看锁的信息
1 执行 EXEC SP_LOCK
报告有关锁的信息
2 查询分析器中按Ctrl+2可以看到锁的信息