SQL Server的可序列化隔离级别是否锁定整个表


9

我和我的一位同事讨论了使用可序列化隔离级别的含义。他说它锁定了整个表,但是我不同意告诉他它有可能,但是它尝试应用范围锁,并且没有应用真正的序列化,如下所述:Serializable Isolation Level

我在文档中也找不到“锁定整个表”的任何内容:SET TRANSACTION ISOLATION LEVEL

该文档陈述了有关范围锁的许多信息,因此从理论上讲,您可以通过仅具有范围锁来锁定整个表,该范围锁可以锁定表中可能值的整个范围,但不会锁定表。

我在这里完全错了吗?它是否实际上锁定了整个表?

Answers:


16

虽然升级

可序列化隔离级别下的锁升级可能与其他隔离级别发生的情况相同。

  • 正确的索引可以帮助避免将锁升级到一个点
  • 锁定许多索引将增加锁定升级的可能性;单个语句的对象之间的计数累计

一些使用单个表和单个索引的快速示例。Id是表上的主键和聚集索引。

一排

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id = 138; --One value

ROLLBACK

对于单个Id值,锁定是最小的。

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |           1 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |           1 |
+--------------+---------------+---------------+-------------+

多行

但是,如果我们开始在范围内工作,锁将上升:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 5000; -- Small range

ROLLBACK

现在,我们在更多键上拥有更多排他锁:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| RangeX-X     | Comments      | KEY           |        2429 |
| IX           | Comments      | OBJECT        |           1 |
| IX           | Comments      | PAGE          |          97 |
+--------------+---------------+---------------+-------------+

更多行

这将一直持续到我们达到临界点:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN

UPDATE c
SET c.Score = 2147483647 
FROM dbo.Comments AS c
WHERE c.Id BETWEEN 1 AND 11655; --Larger range

ROLLBACK

尝试进行锁升级并成功:

+--------------+---------------+---------------+-------------+
| request_mode | locked_object | resource_type | total_locks |
+--------------+---------------+---------------+-------------+
| X            | Comments      | OBJECT        |           1 |
+--------------+---------------+---------------+-------------+

请注意

在这里分开两个概念很重要:隔离级别将是可序列化的,无论采取哪种类型的锁。查询选择隔离级别,存储引擎选择锁。可序列化并不总是会导致范围锁定-存储引擎可以选择仍然符合隔离级别的任何一种锁定。


5

如果搜索谓词上有索引,则可以将其用于范围锁定

即,从范围的第一行到下一行锁定。以及从第三行到第二行,依此类推。直到范围的最后一行。因此,本质上有许多行锁,但是它也阻止了插入值的范围,也阻止了“中间”值(锁定范围)。

为此,您(SQL Server)需要使用一个索引。没有索引来进行锁定(谓词上的索引),您将(据我所知)将获得表锁。

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.