什么时候更喜欢悲观的交易隔离模型而不是乐观的?

时间:2010-11-03 15:04:52

标签: sql-server database database-design transactions locking

我是否正确理解表/行锁定提示正用于并发的悲观事务(TX)隔离模型
换句话说,在SQL Server(2005及更高版本)提供的乐观TX隔离的参与期间何时可以使用表/行锁定提示?

如果后者提供内置乐观(也就是快照又称版本控制)并发隔离,那么在SQL Server2005 +中需要悲观的TX隔离级别/提示吗?
我确实读到悲观的选择是遗留的,不再需要了,尽管我有疑问。

此外,拥有内置SQL Server2005 +的乐观(即快照又称版本控制)TX隔离级别, 什么时候需要手动编写乐观并发功能?

最后一个问题的灵感来自阅读:

描述自定义编码以在SQL Server中提供版本控制。

3 个答案:

答案 0 :(得分:5)

乐观并发需要更多资源,并且在发生冲突时更加昂贵。

两个会话可以读取和修改值,只有在尝试同时应用更改时才会发生冲突。这意味着在并发更新的情况下,两个值都应该存储在某个地方(当然这需要资源)。

此外,当发生冲突时,通常应回滚整个事务或重新获取光标,这也很昂贵。

悲观并发模型使用锁定,从而降低并发性,但提高了性能。

如果有两个并发任务,第二个任务等待锁定释放可能比花费CPU时间和磁盘I/O两个同时工作更便宜,然后更多滚动支持不那么幸运的工作并重做它。

说,你有这样的查询:

UPDATE  mytable
SET     myvalue = very_complex_function(@range)
WHERE   rangeid = @range

very_complex_functionmytable本身读取一些数据。换句话说,此查询会转换共享mytable值的range子集。

现在,当两个函数在同一范围内工作时,可能有两种情况:

  1. 悲观:第一个查询锁定,第二个查询等待它。第一个查询在10秒完成,第二个查询也完成。总计:20秒。

  2. 乐观:两个查询都独立工作(在同一输入上)。它在它们之间共享CPU时间加上切换时的一些开销。他们应该将他们的中间数据保存在某个地方,因此数据存储两次(这意味着两次I/O或内存)。假设几乎在同一时间完成,15秒。

    但是,当提交工作时,第二个查询将发生冲突,并且必须回滚其更改(例如,它需要相同的15秒)。然后,它需要再次重新读取数据并使用新的数据集(10秒)重新开始工作。

    因此,两个查询的完成时间晚于悲观锁定:1540秒与1020

  3.   

    如果后者提供内置乐观(又称快照又称版本控制)并发隔离,那么在SQL Server2005 +中需要悲观的TX隔离级别/提示吗?

    乐观的隔离级别是乐观的。当期望对您的数据产生高争用时,您不应该使用它们。

    BTW,SQL Server 2000也提供了乐观隔离(对于读取查询)。

答案 1 :(得分:2)

我在这里有一个详细的答案:Developing Modifications that Survive Concurrency

答案 2 :(得分:0)

我认为这里的术语有些混乱。

乐观锁定/乐观并发/ ...技术是用于避免以下情况的编程技术:

  • 启动交易
  • 读取数据,在其上设置“读取”锁定以防止对我们的数据进行任何删除/修改
  • 在用户屏幕上显示数据
  • 等待用户输入,锁定仍然有效
  • 等待用户输入,锁定仍然阻止任何写入/修改
  • 用户输入永远不会出现(无论出于何种原因)
  • 交易超时(这通常不是很快,因为必须给予用户合理的时间输入他的输入。)

乐观锁定将其替换为以下内容:

  • 启动交易阅读
  • 读取数据,在其上设置“读取”锁定以防止对我们的数据进行任何删除/修改
  • 结束事务READ,释放刚刚设置的读锁定
  • 在用户屏幕上显示数据
  • 等待用户输入,但可以通过其他交易同时修改/删除数据
  • 用户输入到达
  • 启动交易WRITE
  • 验证数据是否保持不变,如果有
  • 则引发异常
  • 应用用户更新
  • 结束交易WRITE

因此,获取一些数据并更改和更新它们的单个“用户事务”由两个不同的“数据库事务”组成。通常称为“隔离级别”的内容适用于那些数据库事务。您引用的“乐观锁定”适用于“用户事务”。

事情进一步复杂化,从广义上讲,“隔离数据库事务部分”可能有两种完全不同的策略:

  • MVCC
  • 两相锁定

我认为“快照版本控制隔离级别”意味着MVCC技术(以及其各种可能的变体之一)正用于数据库事务。其他通常已知的隔离级别更适用于使用2PL作为序列化(/隔离)技术的事务隔离。 (将它们混合起来可能会变得混乱......)