一 SQL Server 锁类型的说明

在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使用加锁功能说明:

  • NOLOCK(不加锁):SQL Server在读取数据时不加任何锁。在这种情况下,用户可能读取到未完成事务或者回滚中的数据,即所谓的“脏数据”。仅应用于SELECT语句。    
  • HOLDLOCK(保持锁): SQL Server会将此共享锁保持至整个事务结束,而不会再途中释放。也就是说,共享锁保留到事务完成,而不是在相应的表、行、或数据页不再需要时立即释放锁。等同于SERIALIZABLE。
  • PAGLOCK(页锁): 在通常使用单个表锁的地方采用页锁。READCOMMITTED用与运行在提交读隔离级别的事务相同的锁语义执行扫描。
  • READPAST:跳过锁定行,此选项导致事务跳过由其它事务锁定的行(这些行平常会显示在结果集内),而不是阻塞该事务,使其等待其它事务释放在这些行上的锁。仅用与SELECT语句。
  • READUNCOMMITTED: 等同于NOLOCK,用与运行在可重复读隔离级别的事务相同的锁语义执行扫描。
  • ROWLOCK:使用行级锁,而不适用粒度更粗的页级锁和表级锁。SERIALIZABLE用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于HOLDLOCK。
  • TABLOCK: 使用表锁代替粒度更细的行级锁或页级锁。在语句结束前,SQL Server一直持有该锁。但是,如果同时制定HOLDLOCK,那么在事务结束之前,锁将被一直持有。
  • UPDLOCK: 读取表时使用更新锁,而不使用共享锁,并将锁一直保留到语句或事务的结束。UPDLOCK的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没有被更改。
  • XLOCK: 使用排它锁并一直保持到语句处理的所有数据上的事务结束时。可以使用PAGLOCK或TABLOCK指定该锁,这种情况下排它锁适用于适当级别的粒度。至于锁定多少条记录的问题,sql默认的锁定行本来就是行级别锁定的,所以你用TOP 1指定只锁定一条记录就好。 SELECT TOP 1 * FROM dbo.Customer  WITH(UPLOCK,READPAST)

二 死锁与死锁解除

1. 死锁

  使用或管理数据库都不可避免的涉及到死锁,一旦发生死锁,数据相互等待对方资源的释放,会阻止对数据的访问,严重会造成DB挂掉,当资源被锁定,无法被访问时,可以终止访问DB的那个session来达到解锁的目的(即Kill掉造成锁的那个进程)。

  在两个或多个任务中,如果每个任务锁定了其它任务试图锁定的资源,此时会造成这些任务永久阻塞,从而出现死锁。例如:

    • 事务A 获取了行1的共享锁
    • 事务B获取了行2的共享锁
    • 现在,事务A请求行2的排它锁,但在事务B完成并释放其对行2的共享锁之前被阻塞。
    • 现在,事务B请求获取行1的排它锁,但在事务A完成并释放其行1持有的共享锁之前被阻塞。        

  事务B完成之后事务A才能完成,但是事务B由事务A阻塞。该条件也称为循环依赖关系:事务A依赖于事务B,事务B通过对事务A的依赖关系关闭循环。

  除非摸个外部进程断开死锁,否则死锁中的两个事务都将无线期等待下去。SQL Server数据库引擎死锁监视器定期检查陷入死锁的任务。如果监视器检测到循环依赖关系,将选择其中一个任务作为牺牲品,然后终止其事务并提示错误。这样,其它任务就可以完成其事务。对于事务以锁雾终止的应用程序,它还可以重试该事务,但通常要等到其它一起陷入死锁的其它事务完成后执行。

2. 死锁检测

  • SQL Server数据库引擎自动检测SQL Server中的死锁循环。数据库引擎选择一个会话作为死锁牺牲品,然后终止当前事务来打断死锁。
  • 查看DMV:sys.dm_tran_locks (SELECT resource_type,resource_description,resource_associated_entity_id,request_mode,request_status,request_owner_type FROM sys.dm_tran_locks WHERE resource_type!='DATABASE')  
  • SQL Server Profile能够直观的显示死锁的图形事件。

  

  死锁示例:

    第一个连接中执行:

    

  1. BEGIN TRAN
  2. UPDATE dbo.Customer SET NRIC='' WHERE TransactionNumber=6
  3. WAITFOR DELAY '00:00:30'
  4. UPDATE dbo.Employee SET ts=1111 WHERE TransactionNumber=1
  5. COMMIT

    第二个连接中执行

  1. BEGIN TRAN
  2. UPDATE dbo.Employee SET ts=1111 WHERE TransactionNumber=1
  3. WAITFOR DELAY '00:00:10'
  4. UPDATE dbo.Customer SET NRIC='' WHERE TransactionNumber=6
  5.  
  6. COMMIT

  如果两个连接同时执行数据库(SQL Server2008)会自动检测到死锁,终止其中一个进程。

MSSqlserver的锁模式介绍的更多相关文章

  1. oracle 锁的介绍 (转)

    本文转自:http://blog.csdn.net/gyb2013/article/details/6929697 一.什么是锁: Oracle的锁机制是一种轻量级的锁定机制,不是通过构建锁列表来进行 ...

  2. SQL 锁的介绍

    锁的概述 一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏 ...

  3. Mysql锁机制介绍

    Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...

  4. 无锁模式的Vector

    这两天学习无锁的并发模式,发现相比于传统的 同步加锁相比,有两点好处1.无锁 模式 相比于 传统的 同步加锁  提高了性能 2.无锁模式 是天然的死锁免疫 下来介绍无锁的Vector--- LockF ...

  5. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等,在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类 ...

  6. rsync的介绍及参数详解,配置步骤,工作模式介绍

    rsync的介绍及参数详解,配置步骤,工作模式介绍 rsync是类unix系统下的数据镜像备份工具.它是快速增量备份.全量备份工具. Sync可以远程同步,支持本地复制,或者与其他SSH.rsync主 ...

  7. Java 种15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁等等…

    Java 中15种锁的介绍 1,在读很多并发文章中,会提及各种各样的锁,如公平锁,乐观锁,下面是对各种锁的总结归纳: 公平锁/非公平锁 可重入锁/不可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲 ...

  8. STM32三种BOOT模式介绍

    一.三种BOOT模式介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启 ...

  9. Java中15种锁的介绍

    作者:搜云库技术团队 原文:https://segmentfault.com/a/1190000017766364 1. Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观 ...

随机推荐

  1. scikit-learn:3.4. Model persistence

    參考:http://scikit-learn.org/stable/modules/model_persistence.html 训练了模型之后,我们希望能够保存下来,遇到新样本时直接使用已经训练好的 ...

  2. WCF服务寄宿IIS与Windows服务

      WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的 ...

  3. linux 文本编辑器

    文本编辑器 文本编辑器是Linux操作系统中的重要工具.其中,VI是使用最广泛的文本编辑器,其可以在任何shell中使用.此外,Red Hat Enterprise Linux6 还提供了gedit工 ...

  4. TP数据删除

    [数据删除及执行原生sql语句] delete()  返回受影响的记录条数 $goods -> delete(30);   删除主键值等于30的记录信息 $goods -> delete( ...

  5. CodeIgniter框架——源码分析之Config.php

    CI框架的配置信息被存储在$config数组中,我们可以添加自己的配置信息或配置文件到$config中: $this->config->load('filename'); //加载配置文件 ...

  6. (转)gethostbyname() -- 用域名或主机名获取IP地址

    struct hostent *gethostbyname(const char *name); 这个函数的传入值是域名或者主机名,例如"www.google.cn"等等.传出值, ...

  7. 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集

    [BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...

  8. 阻塞(sleep等等)区别 中断(interrupt)+ 中断的意义

    不客气地说,至少有一半人认为,线程的"中断"就是让线程停止.如果你也这么认为,那你对多线程编程还没有入门. 在java中,线程的中断(interrupt)只是改变了线程的中断状态, ...

  9. Nuxt使用scss

    Nuxt中使用scss也很简单,分简单的几步就OK 一.安装scss依赖 用IDE打开项目,在Terminal里通过 npm i node-sass sass-loader scss-loader - ...

  10. Linux考试题附答案

    一.选择题 1.在登录Linux时,一个具有唯一进程ID号的shell将被调用,这个ID是什么(B)? A.NID B.PID C.UID D.CID 2.下面哪个目录存放用户密码信息(B) A./b ...