乐观并发需要事务吗?

Transaction Required with Optimistic Concurrency?

通读这个问题,有几处提到乐观并发在解决过程中由于事务中止而成本更高:

Optimistic vs. Pessimistic locking

如果您正在执行单个更新语句,通常您会设计 where 子句以确保在发生冲突时不进行更新。 IE。您将在 where 子句中包含原始行状态。如果其他人编辑了该行并且存在冲突,由于 where 子句,更新语句将只更新零条记录。 您不需要中止任何事务,因为您的更新 没有做出任何更改。您只需检查查询修改的行数(通常为一或零),如果修改为零,则向用户提供解决方案。

除非你有多个操作 必须与更新一起是原子的,我认为你不需要事务带有 where 子句的单个更新以支持乐观并发。但也许我遗漏了一个细微差别。

您是否需要针对单个更新语句的事务,该语句具有基于原始行状态(对于乐观并发)选择的格式正确的 where 子句?

一般来说,您永远不需要任何单个 DML 语句(插入、更新、删除)的事务。每个单独的 DML 语句都是原子的。也就是说,它作为一个整体成功或失败。事务允许您将多个 DML 查询分组到一个单一的原子工作单元(以便它们作为一个组成功或失败)。

话虽如此,我通常总是使用事务更新。这样,更新模式在所有 update/saves 中都是通用的,我不必担心我正在执行多少次更新(或者因为我添加了第二条更新语句而记得添加事务)。

说了这么多,我认为这并不是您问题的真正答案。

大多数现代网络应用程序的流程类似于:

  1. 从数据库中获取数据并显示
  2. 让用户做他们的事。
  3. 更新数据库

第 2 步将比其他两个步骤花费更长的时间。并发模型对此流程没有帮助,因为您无法在步骤 1 中打开事务并在步骤 3 中关闭它。那么您如何确保更新的数据与显示的数据相同。虽然格式正确的更新可能会阻止更新的发生,但这只是问题的一部分,因为您还必须让用户知道他们的更新失败。

并发选项仅对第 3 步中的处理真正有帮助。如果该过程如下所示:

  1. 从数据库读取数据
  2. 检查数据是否改变
  3. 如果没有改变,更新它。
  4. 将更改保存到数据库

悲观并发保证数据在步骤1和步骤4之间不会发生变化;乐观并发并不能保证任何事情。

我想我的意思是,您是否围绕单个更新语句进行事务不会影响乐观并发或悲观并发。应该使用选择的模型,但两种并发模型都需要处理数据更改。