我一直在阅读有关数据库隔离级别和TransactionScope here,here和here的信息,但是似乎没有人回答我的问题。我遇到的问题是一个简单的读写问题。
下面将描述一个具体方案
Prcess1和process2无法互相通信,我希望数据库级解决方案能够保持这种状态。我知道隔离级别可序列化解决了该问题,因为在步骤2中获取的读取锁定阻止了步骤3的成功。
为了找到较少限制的隔离级别,我还阅读了ReadCommitted和行版本控制。根据{{3}}
的这段文字锁定和行版本控制可防止用户读取未提交的数据 并防止多个用户尝试更改相同的数据 同时。在没有锁定或行版本控制的情况下,执行查询 通过返回数据可能会产生意外结果 数据库中尚未提交的文件
似乎暗示行版本控制可以解决读取和写入问题。在步骤4中,使用行版本控制,数据库应该能够检测到它正在尝试更改自步骤2中的读取以来其版本已更改的行。但是我的实验证明这不是行为。 将ReadCommited隔离和数据库的READ_COMMITTED_SNAPSHO设置为ON后,步骤4成功,状态更新为Shipped。
我的问题是,除了隔离级别“可序列化”之外,是否还有另一种数据库级别的解决方案来解决上述读写问题?
答案 0 :(得分:1)
SQL Server中行的版本控制是什么(这也等同于其他数据库中的多版本并发控制MVCC的工作方式)-对于每个更改的行,它都会维护一个单独的版本,以便如果对该行有读取请求,它利用该版本而不是引用尚未提交的行。这是实现并发读取的一种更好的方式,然后不需要并发锁定,因此在所有主要数据库中都可以实现。现在,您可以了解为什么使用行版本控制(基于语句或事务级别的读取一致性)只能保证一致性读取(使用尚未提交的事务开始更改之前使用的数据版本)。
如果您仅从数据库方面寻求解决方案,我认为可序列化隔离级别是您最好的选择。假设没有多少事务会同时在同一数据行上进行操作,那么您持有锁定的时间将是最少的。
另一种解决方案是使用表中的version列使用开放式并发控制。后面的事务将在update子句中具有“ where version = 1”,该语句将返回0行更新,因为第一个事务已将版本增加到2行。在应用程序端可以将其视为逻辑错误,并相应地传播消息。