2024年4月2日发(作者:)

SQLServer中数据所的类型:

HOLDLOCK将共享锁保留到事务完成,而不是在相应的表、行或数据页不

再需要时就立即释放锁。HOLDLOCK等同于SERIALIZABLE。

NOLOCK不会发出共享锁,并且不会提供排它锁。当此选项生效时,可能

会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅

应用于SELECT语句。

PAGLOCK在通常使用单个表锁的地方采用页锁。

READCOMMITTED用与运行在提交读隔离级别的事务相同的锁语义执行扫

描。默认情况下,SQLServer2000在此隔离级别上操作。

READPAST跳过锁定行。此选项导致事务跳过由其它事务锁定的行(这些

行平常会显示在结果集内),而不是阻塞该事务,使其等待其它事务释放

在这些行上的锁。READPAST锁提示仅适用于运行在提交读隔离级别的事

务,并且只在行级锁之后读取。仅适用于SELECT语句。

READUNCOMMITTED等同于NOLOCK。

REPEATABLEREAD用与运行在可重复读隔离级别的事务相同的锁语义执行

扫描。

ROWLOCK使用行级锁,而不使用粒度更粗的页级锁和表级锁。

SERIALIZABLE用与运行在可串行读隔离级别的事务相同的锁语义执行扫

描。等同于HOLDLOCK。

TABLOCK使用表锁代替粒度更细的行级锁或页级锁。在语句结束前,SQL

Server一直持有该锁。但是,如果同时指定HOLDLOCK,那么在事务结束

之前,锁将被一直持有。

TABLOCKX使用表的排它锁。该锁可以防止其它事务读取或更新表,并

在语句或事务结束前一直持有。

UPDLOCK读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句

或事务的结束。UPDLOCK的优点是允许您读取数据(不阻塞其它事务)并

在以后更新数据,同时确保自从上次读取数据后数据没有被更改。

XLOCK使用排它锁并一直保持到由语句处理的所有数据上的事务结束时。

可以使用PAGLOCK或TABLOCK指定该锁,这种情况下排它锁适用于适当

级别的粒度。

SQL语句加锁例子

1.如何锁一个表的某一行

A连接中执行

SETTRANSACTIONISOLATIONLEVELREPEATABLEREAD

begintran

select*fromtablenamewith(rowlock)whereid=3

waitfordelay'00:00:05'

committran

B连接中如果执行

updatetablenamesetcolname='10'whereid=3--则要等待5秒

updatetablenamesetcolname='10'whereid<>3--可立即执行

2.锁定数据库的一个表

SELECT*FROMtableWITH(HOLDLOCK)

注意:锁定数据库的一个表的区别

SELECT*FROMtableWITH(HOLDLOCK)

其他事务可以读取表,但不能更新删除

SELECT*FROMtableWITH(TABLOCKX)

其他事务不能读取表,更新和删除

加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解

3.游标加锁

下面是SQLServer的存储过程代码:

_GetIndexId

AS

BEGIN

SETNOCOUNTON;

DECLARE@newIdint;

DECLARE@tmpCursorCURSOR;

SET@tmpCursor=CURSORSCROLLDYNAMICSCROLL_LOCKSFOR

SELECTIndexId

FROMIdTableWHERETableId=1FORUPDATE;

OPEN@tmpCursor;

FETCHNEXTFROM@tmpCursorINTO@newId;

IF@@ERROR<>0GOTOFAILURE

UPDATEIdTableSETIndexId=IndexId+1WHERECURRENT

OF

@tmpCursor;

IF@@ERROR<>0GOTOFAILURE

SUCCESS:

CLOSE@tmpCursor;

DEALLOCATE@tmpCursor;

RETURN@newId;

FAILURE:

CLOSE@tmpCursor;

DEALLOCATE@tmpCursor;

RAISERROR(N'获取指标序号失败',16,1);

END

GO

上述存储过程使用了SQLServer2000的T-SQL扩展语法,而不是标准的游

标ForUpdate语法。测试表明,标准SQL92语法的存储过程在多线程或进程的

调用时抛出异常使用T-SQL扩展语法的SCROLL_LOCKS锁而不是Optimistic(乐

观)并发锁。否则,在多进程或线程调用时将抛出异常“乐观并发检查失败。已

在此游标之外修改了该行。”更新字段值Update语句的SQL语法是SQL92的标

准语法。