通读这个问题,有几次提到乐观并发在解决过程中由于中止事务而成本更高:
Optimistic vs. Pessimistic locking
如果您正在执行单个更新语句,通常您会设计 where 子句以确保在发生冲突时不会进行更新。 IE。您可以将原始行状态包含在 where 子句中。如果其他人编辑了该行并且存在冲突,则由于 where 子句,更新语句将仅更新零条记录。 您不需要中止任何交易,因为您的更新没有进行任何更改。您只需检查查询修改的行数(通常为一或零),如果修改为零,则向用户提供解决方案决策。
除非您有多个操作,并且这些操作与更新一起必须是原子的,否则我认为您不需要使用带有 where 子句的单个更新的事务来支持乐观并发。但也许我忽略了一些细微差别。
您是否需要单个更新语句的事务,该事务具有基于原始行状态选择的格式良好的 where 子句(用于乐观并发)?
最佳答案
一般来说,任何单个 DML 语句(插入、更新、删除)都不需要事务。每个单独的 DML 语句都是原子的。也就是说,它整体上是成功还是失败。事务允许您将多个 DML 查询分组为一个原子工作单元(以便它们作为一个组成功或失败)。
话虽如此,我通常总是使用事务更新。这样,更新模式在所有更新/保存中都是通用的,我不必担心我正在执行多少次更新(或者记住添加事务,因为我添加了第二个更新语句)。
说了这么多,我认为这并不是您问题的答案。
大多数现代 Web 应用程序的流程类似于:
- 从数据库获取数据并显示
- 让用户做他们的事情。
- 更新数据库
第 2 步将比其他两个步骤花费更长的时间。并发模型对这个流程没有帮助,因为您无法在步骤 1 中打开事务并在步骤 3 中关闭它。那么如何确保更新的数据与显示的数据相同。虽然格式良好的更新可能会阻止更新发生,但这只是问题的一部分,因为您还必须让用户知道他们的更新失败。
并发选项仅对步骤 3 中的处理有帮助。如果该过程如下所示:
- 从数据库读取数据
- 检查数据是否发生变化
- 如果未更改,请更新。
- 将更改保存到数据库
悲观并发保证步骤1和步骤4之间数据不会发生变化;乐观并发并不能保证任何事情。
我想我是说,无论您是否有围绕单个更新语句的事务,都不会影响乐观并发或悲观并发。应该使用所选的模型,但两个并发模型都需要处理数据更改。
关于sql-server - 乐观并发需要事务吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32149353/