总结:

  (1)对于每个使用到的索引,SQL Server会对上面的键值加U锁。

  (2)SQL Server只对要修改的记录或键加X锁。

  (3)使用到要修改的列的索引越多,锁的数目也会越多。

  (4)扫描的页面越多,意向锁越多。扫描过程中,所有扫描到的记录也会加锁。哪怕没有修改。

  对此,要在UPDATE过程中降低阻塞的几率,可以做以下方面:

  (1)尽量修改少的记录集。

  (2)减少无谓的索引。

  (3)严格避免表扫描的发生。如果只需要修改表的一小部分,要尽量使用Index Seek,避免全表扫描这种执行计划。

  一个常见的DELETE动作要申请的锁:

  Delete的时候也和update一样,需要先找出要更改的数据,然后再进行操作。

  (1)DELETE 的过程先找到符合条件的记录,然后做删除。可以理解为先是一个SELECT ,然后一个DELETE。所以,如果有合适的索引,第一步申请的锁会比较少。

  (2)DELETE 不但把数据行本身删除,还要删除所有相关的索引键,所以一张表上的索引数目越多,锁的数目会越多,越容易发生阻塞。

  为了防止阻塞,我们既不能地不建索引,也不能随随便便建很多索引。对于没有用的索引,去掉比较好。

  一个常见的INSERT动作要申请的锁:

  SQL Server会对新插入的数据本身申请一个X锁。在发生变化的页面申请一个IX锁。由于是新插入的数据,被引用的概率相对小一些,所以发生阻塞的几率也很小。

  小结:

  数据库开发者和DBA想要影响SQL Server锁的申请和释放行为,以缓解阻塞或死锁的问题,需要考虑以下因素:

  1、事务隔离级别的选定:级别越高,隔离度越高,并发也越低。越高的级别SQL Server会不可避免地申请更多的锁。设计应用时,要和用户谈好,尽量选择默认的隔离级别(READ COMMITTED)。

  2、事务的长短和复杂度:决定了事务在SQL Server内部会持续多长时间,也决定了同时在多少张表和索引上申请和持有锁。避免在一个事务里面做很多事情。