关于Sql Server的锁的介绍可以看官方文档或这篇文章《T-SQL查询进阶—理解SQL Server中的锁》的介绍。

查看锁可以通过使用sys.dm_tran_locks这个DMV或者用Profile查看器。用锁锁定的对象可以从行到数据库。

Sql Server的锁大致分为几种:

  • 共享锁(S锁):用于读取数据时所加的锁,默认是读取前加共享锁,读取完一行就释放。共享锁之间不互斥;
  • 拍他锁(X锁):用于修改数据,排斥其他所有的锁;
  • 更新锁(U锁):相当于是S锁+U锁,用于更新;
  • 意向锁(IS,IU,IX):SQL Server锁定一个粒度比较低的资源时,会在其父资源上加上意向锁,告诉其他查询这个资源的某一部分已经上锁。

可以看到Sql Server对于查询一般是要加共享锁的。

下面讲讲死锁,死锁的发生有几个条件:资源的互斥性(mutual exclusion);占有并等待(hold and wait);不可剥夺(no preemption);循环等待(bounded waiting)。

死锁的处理:当Sql Server发生的死锁被检测到时,系统会自动决定终止其中一个进程让其它进程可以继续执行下去,被中断的进程会报错1205的错误,如下。

deadlock

死锁的预防正是程序员所要考虑到的问题。如何将死锁减至最少,官方文档里有提供一些建议:

  • 按同一顺序访问对象
  • 避免事务中的用户交互。
  • 保持事务简短并处于一个批处理中。
  • 使用较低的隔离级别。
  • 使用基于行版本控制的隔离级别。
    • 将 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON,使得已提交读事务使用行版本控制。
    • 使用快照隔离。
  • 使用绑定连接。

官方文档中有对这些建议的详细解释。

对于锁,Sql Server提供了一些Hint,可以用来在程序中人工干预锁的一些属性,官方文档里有详细介绍。

Leave a Reply

Your email address will not be published.

Post Navigation