jrara Asked: 2011-08-19 04:41:54 +0800 CST2011-08-19 04:41:54 +0800 CST 2011-08-19 04:41:54 +0800 CST 什么是阻塞,它是如何发生的? 772 我试图在 SQL Server 中找到一些关于阻塞的信息,但我找不到关于它是什么以及它是如何发生的简明解释。你能启发我吗? sql-server locking 2 个回答 Voted Best Answer Richard 2011-08-19T05:05:36+08:002011-08-19T05:05:36+08:00 类比 有时使用远离计算机的类比会有所帮助。 假设你有一个球和两个孩子。任何时候只有一个孩子可以拿球。但是,如果其中一个孩子拿到球并且因为分心(例如看电视)而没有放手,那么另一个孩子将无法玩球。 另一个孩子被阻止使用该资源。 例如,如果我们将其与电视进行比较,那么几个孩子可以在任何时候看电视。 锁具 如果我们转到数据库世界,我们会发现使用资源的方式有很多种(就像我们上面的两个示例一样)。我们可以执行“读取”,也可以执行“写入”。 当我们要读取数据时,没有理由其他人不能读取数据——就像两个人看电视一样。但是,如果我们要写入数据,那么我们需要确保没有其他人在查看它。如果他们在我们写它的时候读它,他们会得到“脏”读。(意思是,他们会看到部分写出的数据,这将是无效的。) 为了确保这些脏读永远不会发生,我们有两种主要类型的锁,读锁和排他锁。 读锁 您可以在任何给定时间从同一数据源读取多个不同的连接。但是为了确保没有人在读取数据时更改该数据,他们取出了读取锁。 一旦一个连接对一条数据有了读锁,所有其他连接必须等到读锁释放后才能写入数据。但是,其他人可以在同一条数据上取出自己的读取锁。 排他锁 如果一个连接想要更新/插入/删除一条数据,他们必须拿出一个排他锁。这可以防止任何其他连接也对数据进行锁定(使锁定独占该连接)。 当一个连接对数据具有排他锁时,其他连接不能读取数据。通过确保在写入数据时没有人可以读取数据,这有助于防止脏读。 阻塞 “阻塞”只是一个术语,它意味着当另一个连接想要读取或写入资源时,一个连接正在对资源进行锁定。这并不一定意味着所有者连接不会释放它,只是它当前持有它。 将此与儿童拿着球的情况进行比较。拿着球的孩子正在阻止所有其他孩子拿着球。 僵局 我知道你没有问这个,但这只是进入死锁的一步(它与阻塞非常直接相关)。 当你有两个连接,每个连接都有一个锁,但他们想要彼此的资源时,就会发生死锁。在这种情况下,就像两个孩子每个人都有一个球,但想要对方的球。 像孩子一样,这些联系根本不愿意分享。每个连接都需要访问这两个资源才能继续。但是,它们处于永久阻塞状态。在这种状态下,父母(DBMS)必须进来并选择一个失败者,以便其中一个孩子(连接)可以访问这两种资源。 一旦完成“获胜”连接,它就会释放资源,然后另一个(“失败”)连接可以再次尝试获取这两个资源。 因此,死锁的概念是您有两个相互阻塞的资源。 在这里,您可以阅读有关 SQL Server 必须提供的所有不同类型的锁以及可能导致阻塞/死锁的不同资源的更多信息。这篇文章很旧,但它仍然适用于 SQL Server 2000 到 2008 R2。(在 SQL Server 的更高版本中添加了更多类型的锁,但这将为您提供一个起点。) Aaron Bertrand 2011-08-19T08:35:24+08:002011-08-19T08:35:24+08:00 理查德很好的解释,但只是想添加官方文档的链接。这些主题是为 SQL Server 2000 编写的,但许多概念在今天保持不变: 理解和避免阻塞 了解 SQL Server 中的锁定 编辑 - 一些补充: 对抗阻塞视频的五种方法- Kendra Little 的一个非常新鲜的视频(今天发布) 作为侦探的 DBA:锁定和阻塞故障排除- Rodney Landrum 如何使用 SQL Profiler 识别阻塞问题- Brad McGehee 所有 3 人都是非常知名的 SQL Server 作者和/或 MVP。
类比
有时使用远离计算机的类比会有所帮助。
假设你有一个球和两个孩子。任何时候只有一个孩子可以拿球。但是,如果其中一个孩子拿到球并且因为分心(例如看电视)而没有放手,那么另一个孩子将无法玩球。
另一个孩子被阻止使用该资源。
例如,如果我们将其与电视进行比较,那么几个孩子可以在任何时候看电视。
锁具
如果我们转到数据库世界,我们会发现使用资源的方式有很多种(就像我们上面的两个示例一样)。我们可以执行“读取”,也可以执行“写入”。
当我们要读取数据时,没有理由其他人不能读取数据——就像两个人看电视一样。但是,如果我们要写入数据,那么我们需要确保没有其他人在查看它。如果他们在我们写它的时候读它,他们会得到“脏”读。(意思是,他们会看到部分写出的数据,这将是无效的。)
为了确保这些脏读永远不会发生,我们有两种主要类型的锁,读锁和排他锁。
读锁
您可以在任何给定时间从同一数据源读取多个不同的连接。但是为了确保没有人在读取数据时更改该数据,他们取出了读取锁。
一旦一个连接对一条数据有了读锁,所有其他连接必须等到读锁释放后才能写入数据。但是,其他人可以在同一条数据上取出自己的读取锁。
排他锁
如果一个连接想要更新/插入/删除一条数据,他们必须拿出一个排他锁。这可以防止任何其他连接也对数据进行锁定(使锁定独占该连接)。
当一个连接对数据具有排他锁时,其他连接不能读取数据。通过确保在写入数据时没有人可以读取数据,这有助于防止脏读。
阻塞
“阻塞”只是一个术语,它意味着当另一个连接想要读取或写入资源时,一个连接正在对资源进行锁定。这并不一定意味着所有者连接不会释放它,只是它当前持有它。
将此与儿童拿着球的情况进行比较。拿着球的孩子正在阻止所有其他孩子拿着球。
僵局
我知道你没有问这个,但这只是进入死锁的一步(它与阻塞非常直接相关)。
当你有两个连接,每个连接都有一个锁,但他们想要彼此的资源时,就会发生死锁。在这种情况下,就像两个孩子每个人都有一个球,但想要对方的球。
像孩子一样,这些联系根本不愿意分享。每个连接都需要访问这两个资源才能继续。但是,它们处于永久阻塞状态。在这种状态下,父母(DBMS)必须进来并选择一个失败者,以便其中一个孩子(连接)可以访问这两种资源。
一旦完成“获胜”连接,它就会释放资源,然后另一个(“失败”)连接可以再次尝试获取这两个资源。
因此,死锁的概念是您有两个相互阻塞的资源。
在这里,您可以阅读有关 SQL Server 必须提供的所有不同类型的锁以及可能导致阻塞/死锁的不同资源的更多信息。这篇文章很旧,但它仍然适用于 SQL Server 2000 到 2008 R2。(在 SQL Server 的更高版本中添加了更多类型的锁,但这将为您提供一个起点。)
理查德很好的解释,但只是想添加官方文档的链接。这些主题是为 SQL Server 2000 编写的,但许多概念在今天保持不变:
理解和避免阻塞
了解 SQL Server 中的锁定
编辑 - 一些补充:
对抗阻塞视频的五种方法- Kendra Little 的一个非常新鲜的视频(今天发布)
作为侦探的 DBA:锁定和阻塞故障排除- Rodney Landrum
如何使用 SQL Profiler 识别阻塞问题- Brad McGehee
所有 3 人都是非常知名的 SQL Server 作者和/或 MVP。