Answers:
类比
有时在计算机之外使用类比很有帮助。
假设您有一个球和两个孩子。任何时候只有一个孩子可以接球。但是,如果其中一个孩子拿到了球并且因为他分心而放弃了球(例如,看电视),那么另一个孩子就不会玩球。
另一个孩子被阻止使用该资源。
例如,如果将其与电视进行比较,那么几个孩子可以在任何一点观看电视。
锁具
如果我们进入数据库世界,就会发现有多种使用资源的方式(就像上面的两个示例一样)。我们可以执行“读取”,也可以执行“写入”。
当我们想要读取数据时,没有理由别人也无法读取数据,就像两个人在看电视一样。但是,如果我们要写入数据,则需要确保没有其他人正在查看它。如果他们在我们编写它时正在阅读它,那么他们将获得“脏”读。(意味着,他们将看到部分写入的数据,这将是无效的。)
为了确保这些脏读不会发生,我们有两种主要类型的锁:读取锁和排他锁。
读锁
您可以在任何给定时间从同一数据源读取多个不同的连接。但是为了确保在读取数据时没有人更改数据,他们将读取锁定。
一旦连接具有对一条数据的读取锁,则所有其他连接必须等到释放读取锁后才能写入数据。但是,其他人可以对同一条数据取出自己的读取锁。
排他锁
如果连接要更新/插入/删除数据,则它们必须取消独占锁定。这样可以防止任何其他连接也对数据进行锁定(使该锁定专用于该连接)。
当连接对数据具有排他锁时,则不能从数据读取其他连接。通过确保在写入数据时没有人可以读取数据,这有助于防止脏读。
封锁
“阻止”只是一个术语,表示一个连接正在对另一个资源进行读取或写入时在资源上持有锁。这不一定意味着所有者连接不会释放它,只是它当前正在持有它。
将此情况与孩子握球的情况进行比较。拿着球的孩子正在阻止所有其他孩子拿着球。
僵局
我知道您没有问这个问题,但这只是陷入僵局的又一步骤(它与阻止直接相关)。
当您有两个都有一个锁的连接,但是它们想要彼此资源时,可能会发生死锁。在这种情况下,就像两个孩子每个都有一个球,但想要另一个孩子的球。
像孩子一样,这些联系根本不愿分享。每个连接都需要访问两个资源才能继续。但是,它们处于永久阻塞状态。在这种状态下,父级(DBMS)必须进入并选择失败者,以便子级(连接)之一可以访问这两种资源。
一旦完成“胜利”连接,它将释放资源,然后另一个(“失败”)连接可以再次尝试获取这两个资源。
因此,死锁的概念是您拥有两个相互阻塞的资源。
在这里,您可以了解有关SQL Server必须提供的所有不同类型的锁以及可能导致阻塞/死锁的不同资源的更多信息。该文章很旧,但是仍然适用于SQL Server 2000到2008 R2。(在更高版本的SQL Server中添加了更多类型的锁,但这将为您提供一个起点。)
理查德的解释很好,但只想添加到官方文档的链接。这些主题是为SQL Server 2000编写的,但如今许多概念仍然相同:
编辑-一些补充:
阻止视频的五种方法 -Kendra Little的非常新鲜的视频(今天发布)
作为侦探的DBA:锁定和阻止故障排除 -Rodney Landrum
如何使用SQL Profiler识别阻塞问题 -作者:Brad McGehee
这3位都是非常知名的SQL Server作者和/或MVP。