标签:不可 取数据 request resource 就是 牺牲品 允许 执行 表锁
在SQL Server数据库中加锁时,除了可以对不同的资源加锁,还可以使用不同程度的加锁方式,即有多种模式,SQL Server中锁模式包括:
1.共享锁(S) 共享锁用于所以的制度数据操作。共享锁是非独占的,允许多个并发事务读取其锁定的资源。默认情况下,数据被读取后,SQL Server立刻释放共享锁。
例如: 执行查询"SELECT * FROM dbo.Customer"时,首先锁定第一页,读取之后,释放对第一页的锁定,然后锁定第二页。这样,就允许在读操作过程中,修改未被锁定的第一页。但是,事务隔离级别链接选项设置和SELECT语句中的锁定设置都可以改变SQL Server的这种默认设置。
执行查询"SELECT * FROM dbo.Customer WITH(HOLDLOCK)"就要求在整个查询过程中,保持对表的锁定,直到查询完成才释放锁定。
2.更新锁(U) 更新锁在修改操作的初始化阶段用来锁定可能要被修改的资源,这样可以避免使用共享锁(S)造成的死锁现象。因为使用共享锁(S)时,修改数据的操作分为两步,首先获得一个共享锁(S),读取数据,然后再将共享锁升级为排它锁(X),然后执行修改操作。这样如果同时又两个或多个事务同时对一个事务申请共享锁,在修改数据的时候,这些事务将共享锁升级为排它锁(X)。这时,这些事务都不会释放共享锁而是一直等待对方释放,这样就造成了死锁。如果一个数据在修改前直接申请更新锁(U),在数据修改的时候再升级为排它锁(X),就可以避免死锁。
3.结构锁(Sch) 执行表的数据定义语言(DDL)操作(例如添加列或除去表)时使用架构修改(Sch-M)锁。当编译查询时,使用架构稳定性(Sch-S)锁。架构稳定性锁不阻塞任何事务锁,包括排它锁。因此在编译查询时,其它事务(包括在表上有排它锁的事务)都能继续运行。但不能在表上执行DDL操作。
4.意向锁(I) 意向锁说明SQL Server有在资源的底层获得共享锁或排它锁的意向。数据库引擎使用意向锁来保护共享锁或排它锁放置在锁层次结构的底层资源上。意向锁之所以命名为意向锁,是因为在较低级别锁前可获取它们,因此会通知意向将锁放置在较低级别上。
例如:表级的共享意向锁说明事务意图讲排它锁释放在表中的页或者行。
意向锁有可以分为:
共享意向锁(IS):事务意图在共享意向锁所锁定的底层资源上放置共享锁来读取数据。
排它意向锁(IX):事务意图在共享锁锁定的资源上放置排它锁来修改数据。
共享式排它意向锁(SIX):事务允许其他事务使用共享锁来读取顶层资源,并意图在该资源低层上放置排它锁。
意向锁的两种用途:
5.大容量更新锁(BU) 当将数据大容量复制到表,且指定了TABLOCK提示或者使用sp_tableoption设置了table lock on bulk表选项时,将使用大容量更新锁。大容量更新锁允许进程将数据并发大容量复制到同一表,同时防止其它不进行大容量复制数据的进程访问该表。
SQL Server使用加锁功能说明:
1. 死锁
使用或管理数据库都不可避免的涉及到死锁,一旦发生死锁,数据相互等待对方资源的释放,会阻止对数据的访问,严重会造成DB挂掉,当资源被锁定,无法被访问时,可以终止访问DB的那个session来达到解锁的目的(即Kill掉造成锁的那个进程)。
在两个或多个任务中,如果每个任务锁定了其它任务试图锁定的资源,此时会造成这些任务永久阻塞,从而出现死锁。例如:
事务B完成之后事务A才能完成,但是事务B由事务A阻塞。该条件也称为循环依赖关系:事务A依赖于事务B,事务B通过对事务A的依赖关系关闭循环。
除非摸个外部进程断开死锁,否则死锁中的两个事务都将无线期等待下去。SQL Server数据库引擎死锁监视器定期检查陷入死锁的任务。如果监视器检测到循环依赖关系,将选择其中一个任务作为牺牲品,然后终止其事务并提示错误。这样,其它任务就可以完成其事务。对于事务以锁雾终止的应用程序,它还可以重试该事务,但通常要等到其它一起陷入死锁的其它事务完成后执行。
2. 死锁检测
死锁示例:
第一个连接中执行:
BEGIN TRAN UPDATE dbo.Customer SET NRIC=‘1000‘ WHERE TransactionNumber=6 WAITFOR DELAY ‘00:00:30‘ UPDATE dbo.Employee SET ts=1111 WHERE TransactionNumber=1 COMMIT
第二个连接中执行
BEGIN TRAN UPDATE dbo.Employee SET ts=1111 WHERE TransactionNumber=1 WAITFOR DELAY ‘00:00:10‘ UPDATE dbo.Customer SET NRIC=‘1000‘ WHERE TransactionNumber=6 COMMIT
如果两个连接同时执行数据库(SQL Server2008)会自动检测到死锁,终止其中一个进程。
标签:不可 取数据 request resource 就是 牺牲品 允许 执行 表锁
原文地址:https://www.cnblogs.com/wangjunqiao/p/9532071.html