什么是阻塞,它如何发生?


20

我试图找到有关SQL Server中阻塞的一些信息,但找不到关于它是什么以及它如何发生的简明解释。你能开导我吗?

Answers:


23

类比

有时在计算机之外使用类比很有帮助。

假设您有一个球和两个孩子。任何时候只有一个孩子可以接球。但是,如果其中一个孩子拿到了球并且因为他分心而放弃了球(例如,看电视),那么另一个孩子就不会玩球。

另一个孩子被阻止使用该资源。

例如,如果将其与电视进行比较,那么几个孩子可以在任何一点观看电视。

锁具

如果我们进入数据库世界,就会发现有多种使用资源的方式(就像上面的两个示例一样)。我们可以执行“读取”,也可以执行“写入”。

当我们想要读取数据时,没有理由别人也无法读取数据,就像两个人在看电视一样。但是,如果我们要写入数据,则需要确保没有其他人正在查看它。如果他们在我们编写它时正在阅读它,那么他们将获得“脏”读。(意味着,他们将看到部分写入的数据,这将是无效的。)

为了确保这些脏读不会发生,我们有两种主要类型的锁:读取锁和排他锁。

读锁

您可以在任何给定时间从同一数据源读取多个不同的连接。但是为了确保在读取数据时没有人更改数据,他们将读取锁定。

一旦连接具有对一条数据的读取锁,则所有其他连接必须等到释放读取锁后才能写入数据。但是,其他人可以对同一条数据取出自己的读取锁。

排他锁

如果连接要更新/插入/删除数据,则它们必须取消独占锁定。这样可以防止任何其他连接也对数据进行锁定(使该锁定专用于该连接)。

当连接对数据具有排他锁时,则不能从数据读取其他连接。通过确保在写入数据时没有人可以读取数据,这有助于防止脏读。

封锁

“阻止”只是一个术语,表示一个连接正在对另一个资源进行读取或写入时在资源上持有锁。这不一定意味着所有者连接不会释放它,只是它当前正在持有它。

将此情况与孩子握球的情况进行比较。拿着球的孩子正在阻止所有其他孩子拿着球。

僵局

我知道您没有问这个问题,但这只是陷入僵局的又一步骤(它与阻止直接相关)。

当您有两个都有一个锁的连接,但是它们想要彼此资源时,可能会发生死锁。在这种情况下,就像两个孩子每个都有一个球,但想要另一个孩子的球。

像孩子一样,这些联系根本不愿分享。每个连接都需要访问两个资源才能继续。但是,它们处于永久阻塞状态。在这种状态下,父级(DBMS)必须进入并选择失败者,以便子级(连接)之一可以访问这两种资源。

一旦完成“胜利”连接,它将释放资源,然后另一个(“失败”)连接可以再次尝试获取这两个资源。

因此,死锁的概念是您拥有两个相互阻塞的资源。


在这里,您可以了解有关SQL Server必须提供的所有不同类型的锁以及可能导致阻塞/死锁的不同资源的更多信息。该文章很旧,但是仍然适用于SQL Server 2000到2008 R2。(在更高版本的SQL Server中添加了更多类型的锁,但这将为您提供一个起点。)


1
@Richard,就像您提到的那样,如果发生死锁,则DBMS会进入并选择失败者。.DBMS是否自动完成此操作?还是设计不良的系统(经常遇到死锁的系统)会停止运行,直到有人启动DBMS来这样做?
CenterOrbit

2
对于SQL Server,这是自动完成的(只要数据库可以检测到死锁)。例如,如果它实际上是一个活锁,则可能无法检测到它。
理查德

很好,非常彻底的回答理查德。关于活动锁的另一点(实际上不应与死锁进行比较或与死锁相关,它只是普通的旧阻塞)... SQL将阻止在排他锁正在等待的情况下采取进一步的锁,即IIRC在4个连续重叠的共享锁之后。
马克·斯托里·史密斯

5

理查德的解释很好,但只想添加到官方文档的链接。这些主题是为SQL Server 2000编写的,但如今许多概念仍然相同:

了解并避免阻塞

了解SQL Server中的锁定

编辑-一些补充:

这3位都是非常知名的SQL Server作者和/或MVP。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.