为什么Serializable Isolation级别会导致死锁和并发问题?

时间:2016-08-19 00:52:47

标签: sql-server concurrency isolation-level database-deadlocks

我知道带有范围锁和读数的读数的理论。写锁在事务的持续时间内以可序列化的隔离级别保持。我可以理解有人发表声明并且所有事情都是平等的,可序列化隔离可能,但不是必然的,导致并发性低于任何其他隔离级别'。但是所有博客/文档都说明了这一点,较低的并发性和较高的死锁似乎是肯定的。我试图理解为什么在我的特定情况下它应该在实际意义上如此。以下是我的问题

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

  2. 为什么僵局会增加?这些是由于索引页面的更新吗?但这些可能发生在任何隔离级别,而不是快照隔离。那么为什么要单独列出Serializable Isolation level?

  3. 我当然会接受这样的回答:“你根本不知道你的执行计划何时根据用户输入而变坏”。通过设置高于所需的隔离级别,您将使情况变得更糟。因此,设置最适合您的隔离级别

1 个答案:

答案 0 :(得分:1)

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

  

其他事务无法插入新行,其键值将落在当前事务中任何语句读取的键范围内,直到当前事务完成为止。

在文档中,它直接指出范围锁被取出。因此,如果您执行select * from dbo.yourTable where ID between 1 and 50之类的操作,并且表格中目前只有10行(例如ID 1-10),那么您的应用程序将无法执行以下操作:

  • 插入ID 11-50
  • 的所有数据
  • 删除/更新1-10
  • 中的任何一个

如果您需要它,您需要它。但要知道你进入了什么;放置的共享范围锁是不兼容的(读取"将导致阻塞")有很多东西。有关详细信息,请参阅the Lock Compatibility Matrix