【发布时间】:2019-11-06 21:45:45
【问题描述】:
我一直在阅读有关数据库隔离级别和 TransactionScope here、here 和 here 的信息,但似乎没有人回答我的问题。我遇到的问题是一个简单的读写问题。
下面描述一个具体的场景
- process1 读取初始状态:ReadyForShipment
- process2 读取状态:ReadyForShipment
- process1 将状态更改为 Canceled 并提交其事务
- process2 将状态更改为已发货,这是无效的,因为不应发货。
进程 1 和进程 2 不相互通信,我希望数据库级别的解决方案能够保持这种状态。我知道隔离级别 Serializable 解决了这个问题,因为在 step2 中获取的读锁阻止了 step3 成功。
为了找到限制较少的隔离级别,我还阅读了 ReadCommitted 和行版本控制。根据here的这篇文字
锁定和行版本控制可防止用户读取未提交的数据 并防止多个用户尝试更改相同的数据 同时。没有锁定或行版本控制,查询执行 针对该数据可能会通过返回数据产生意想不到的结果 还没有提交到数据库中
这似乎暗示行版本控制可以解决读写问题。在第 4 步中,通过行版本控制,数据库应该能够检测到它正在尝试更改自第 2 步中的读取以来其版本已更改的行。但我的实验证明这不是行为。 将 ReadCommited 隔离和数据库的 READ_COMMITTED_SNAPSHO 设置为 ON,步骤 4 成功,状态更新为已发货。
我的问题是,除了隔离级别Serializable之外,对于上面描述的读写问题,还有其他数据库级别的解决方案吗?
【问题讨论】:
-
Rowversion / Timestamp 对于处理丢失更新问题很有用。
标签: sql-server entity-framework concurrency transactions isolation-level