http://expert.csdn.net/Expert/topic/2218/2218218.xml?temp=.099621
/********** 加锁 ***************
设table1(A,B,C)
A B C
a1 b1 c1
a2 b2 c2
a3 b3 c31)排它锁
新建两个连接
在第一个连接中执行以下语句
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)共享锁
在第一个连接中执行以下语句
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若同时执行上述两个语句,则第二个连接中的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
在第二个连接中执行以下语句
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同时执行,系统会检测出死锁,并中止进程
--------------------------------------------------------------
SET IMPLICIT_TRANSACTIONS ON --用户每次必须显式提交或回滚。否则当用户断开连接时,
--事务及其所包含的所有数据更改将回滚SET IMPLICIT_TRANSACTIONS OFF --自动提交模式。在自动提交模式下,如果各个语句成功
--完成则提交。
update ,insert ,delete是独占锁
考虑独占锁的以下事实
1。只有一个事务可以获得一个资源的独占锁
2。事务不能获得有独占锁资源上的共享锁
3。在资源上的所有共享锁释放后,才能获得它上面的独占锁1 如何锁一个表的某一行
A 连接中执行SET TRANSACTION ISOLATION LEVEL REPEATABLE READbegin transelect * from tablename with (rowlock) where id=3waitfor delay '00:00:05'commit tranB连接中如果执行update tablename set colname='10' where id=3 --则要等待5秒update tablename set colname='10' where id<>3 --可立即执行2 锁定数据库的一个表SELECT * FROM table WITH (HOLDLOCK)
注意: 锁定数据库的一个表的区别SELECT * FROM table WITH (HOLDLOCK)
其他事务可以读取表,但不能更新删除SELECT * FROM table WITH (TABLOCKX)
其他事务不能读取表,更新和删除
SET LOCK_TIMEOUT 3000
或中断某数据库的所有连接来解锁:
use master
go
create proc killspid (@dbname varchar(20))
as
begin
declare @sql nvarchar(500),@temp varchar(1000)
declare @spid int
set @sql='declare getspid cursor for
select spid from sysprocesses where dbid=db_id('''+@dbname+''')'
exec (@sql)
open getspid
fetch next from getspid into @spid
while @@fetch_status < >-1
begin
set @temp='kill '+rtrim(@spid)
exec(@temp)
fetch next from getspid into @spid
end
close getspid
deallocate getspid
end --用法
use master
exec killspid '数据库名'
BEGIN tran
DECLARE @avg-adv money
SELECT @avg-adv = avg(advance)
FROM titles holdlock
WHERE type = "business"
if @avg-adv > 5000
SELECT title from titles
WHERE type="business" and advance >@avg_adv
COMMIT tran
在SQL Server中设定事务隔离级别的方法有三种:
• 会话层设定
语法如下:
SET TRANSACTION ISOLATION LEVEL
{
READ COMMITTED
| READ UNCOMMITTED
| REPEATABLE READ
| SERIALIZABLE
}
系统提供的系统存储过程将在级别1下执行,它不受会话层设定的影响。
• 语法层设定
在SELECT、DECLARE cursor及read text语句中增加选项。比如:
SELECT...at isolation{0|read uncommitted}
注意:语法层的设定将替代会话层的设定。
• 利用关键词设定
─在SELECT语句中,加选项holdlock则设定级别3
─在SELECT语句中,加noholdlock则设定级别0如下程序清单中所列的脚本实例在authors表上持有一个共享锁,它将用户检查服务器当前活动的时间推迟两分钟。
程序清单测试事务隔离等级
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
GO
BEGIN TRAN
SELECT *
FROM authors
WHERE au_lname = 'Green'
WAITFOR DELAY '00:02:00'
ROLLBACK TRAN
GO
Activity Legend(活动图标)表明:当SQL Server检索数据时会去掉页面表意向锁。Current Activity窗口(见图3 - 3 )显示共享锁一直被保持直到事务完成为止(也就是说,直到WAITFOR和ROLLBACK TRAN语句完成)。
使用锁定优化程序提示
让我们再深入考察程序清单的实例。通过改变优化程序提示,用户可以令SQL Server在authors表上设置一个独占表锁(如程序所示)。
BEGIN TRAN
SELECT *
FROM authors (tablockx)
WHERE au_lname = 'Green'
WAITFOR DELAY '00:02:00'
ROLLBACK TRAN
GOSELECT语句使用优化程序提示tablockx来保持独占表锁直到事务结束为止。下表显示了可用的锁定优化程序提示。
锁定优化程序提示及其描述
优化程序提示 优化程序提示描述
holdlock 保持锁定直到事务结束
nolock 检索数据时不使用锁
paglock 使用页面锁
tablock 使用表锁
tablockx 使用独占表锁
updlock 使用更新锁
holdlock优化程序提示能够在整个事务期间保持共享锁,读者在可串行化和可重复读事务隔离等级中对此已很熟悉了。如果用户偶尔想使用共享锁,最好使用系统默认的读交付事务隔离等级并需要使用holdlock优化程序提示。holock优化程序提示与读不交付事务隔离等级有相同的功能,它通过在读数据时不要任何锁定而实现非交付数据的读操作(从而避免了任何独占锁定引起的阻隔)。使用索引和锁定优化程序提示需要注意的是:用户可以将这两种类型的提示结合起来使
用,但必须将索引提示最后列出,这一点很重要。如下程序清单中的代码给出了合法优化程序提示的正确方法。如一个混合优化程序提示
SELECT *
FROM authors (paglock holdlock index=aunmind)