哇哦,这里有很多问题啊。以下是几个答案:
往这个表中插入记录时,是否会锁定整个表?
默认情况下不会,但如果你使用TABLOCK提示或进行某些类型的批量加载操作,则会锁定整个表。
那么,如果从表中查询数据,是否会一直阻塞直到插入完成(我知道有解决方法,但默认情况下呢)?
这个问题有点棘手。如果有人试图从你锁定的表中的页面中选择数据,那么是的,你会阻塞他们。你可以通过在select语句上使用NOLOCK提示或使用已读提交快照隔离来解决这个问题。要了解隔离级别的起点,请查看Kendra Little的隔离级别海报。
它需要多长时间才会导致死锁?那个时间是否取决于服务器的负载,例如,如果负载不大,将需要更长时间才会导致死锁?
死锁并不是基于时间的-它们基于依赖关系。假设我们有这种情况:
- 查询A持有大量锁,并且为了完成他的查询,他需要被查询B锁定的东西。
- 查询B也持有大量锁,并且为了完成他的查询,他需要被查询A锁定的东西。
两个查询都无法继续执行(类似于墨西哥僵局),因此SQL Server认为平局,终止其中一个查询,释放其锁定,并让另一个查询继续执行。SQL Server选择牺牲品是基于撤消更便宜的查询。如果你想变得高级一些,可以在特定查询上使用SET DEADLOCK_PRIORITY LOW,在它们的背后画目标,然后SQL Server将优先终止它们。
有没有一种方法可以监视并查看任何特定时间被锁定的内容?
绝对可以-有动态管理视图(DMV)可以查询,例如sys.dm_tran_locks,但最简单的方式是使用Adam Machanic免费的sp_WhoIsActive存储过程。这是一个真正漂亮的替代sp_who的工具,你可以像这样调用它:
sp_WhoIsActive @get_locks = 1
对于每个正在运行的查询,您都会得到一个小型XML,其中描述了它持有的所有锁。还有一个阻止列,因此您可以看到谁在阻止谁。要解释所持有的锁,您需要检查锁类型的Books Online描述。
如果每个线程都在单个表上执行查询,那么是否有可能发生阻塞? 因此,死锁只能在对多个表进行连接并执行操作的查询中才会发生吗?
信不信由您,单个查询实际上可以产生死锁,是的,查询只能在一个表上死锁。 要了解更多关于死锁的信息,请查看Jeremiah Peschka的The Difficulty with Deadlocks。