为什么序列化隔离级别会导致死锁和并发问题?

问题描述:

我知道这个理论,即带有范围锁定的读取锁定在可序列化隔离级别中的事务持续时间内被保持。我可以理解某人发表声明'所有事情都是平等的,可序列化隔离可能会导致比其他隔离级别更低的并发性。但是所有博客/文档都说明了这一点,并发性和更高的死锁似乎是确定的。我试图理解为什么在我的特殊情况下它应该如此实际。这里是我的问题为什么序列化隔离级别会导致死锁和并发问题?

  1. 如果各个连接不访问同一组记录,可序列化隔离级别会导致较低的并发性吗?我假设一个“精细调整”的OLTP系统,其中每个查询都是一个“点查询”,只返回几行,优化器提出了很好的计划。我也在考虑数据页面而不是索引页面。

  2. 为什么死锁会增加?这些是由于索引页面的更新吗?但是这些可能发生在任何隔离级别,除了快照隔离之外。那么为什么要单独列出可序列化隔离级别?

我当然会回答说'你永远不知道什么时候你的执行计划会因用户输入而变坏。如果设置的隔离级别高于所需的隔离级别,则会使情况恶化。所以设置最适合你的最高隔离级别'

简短的回答是,当你从read uncommitted一直到serializable,你最终会拿出更多不同种类的锁。在一定程度上,这是有道理的;数据库引擎如何能够做出以下保证?

其他事务不能插入具有键值的新行,这些键值落在当前事务中任何语句读取的键的范围内,直到当前事务完成。

进一步在文档中,它直接说出范围锁取出。所以,如果你这样做select * from dbo.yourTable where ID between 1 and 50,并且目前只有10行的表(说的ID 1-10),您的申请将不能够:

  • 插入的标识11-50任何数据
  • 删除/更新任何的1-10

如果你需要它,你需要它。但要知道你在做什么;所放置的共享范围锁与许多内容不兼容(读取“将导致阻塞”)。详情请参阅the Lock Compatibility Matrix

+0

我肯定会同意你,如果连接确实带范围锁。但是,如果2个不同的用户连接访问完全相同的记录/页面的情况很少,您是否仍然保持良好状态? – QFirstLast

+0

使用范围锁定,您正在锁定元结构。也就是说,数据甚至不需要试图将其修改为被阻止的操作(参见上面的项目符号点)。所以,如果你知道你的两个(或更多)应用程序将修改不相交的范围,那么你很好。但我会反驳:为什么你需要在那一点上可序列化的隔离? –

+0

谢谢本。关于“为什么当时需要系列化隔离?”,我们还没有做出决定。我们正在理解每个隔离级别的特点,优缺点并将其应用于我们的情况。你的回应有帮助。我会尝试将你的回答标记为答案。我最后一次尝试的时候,网站并没有让我说“在我这样做之前,我需要一些点数”。 – QFirstLast