首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库IsolationLevel与读写问题

数据库IsolationLevel与读写问题
EN

Stack Overflow用户
提问于 2019-06-25 05:42:36
回答 1查看 90关注 0票数 2

我一直在阅读有关数据库隔离级别和TransactionScope 这里这里这里的文章,但似乎没有人回答我的问题。我的问题是一个简单的读写问题。

下面描述了一个具体的场景

  1. process1读取初始状态: ReadyForShipment
  2. process2读取状态: ReadyForShipment
  3. process1将状态更改为已取消并提交其事务。
  4. process2将状态更改为已发送,这是无效的,因为不应该发送已取消的项。

Prcess1和process2并不相互通信,我希望有一个数据库级的解决方案来保持这种状态。我知道隔离级别Serializable解决了这个问题,因为在step2中获得的读锁阻止了step3的成功。

为了找到一个限制较少的隔离级别,我还阅读了ReadCommitted和行版本控制方面的内容。根据这篇文章来自这里

锁定和行版本控制防止用户读取未提交的数据,并防止多个用户试图同时更改相同的数据。在不进行锁定或行版本控制的情况下,针对该数据执行的查询可能会返回尚未在数据库中提交的数据,从而产生意外的结果。

这似乎意味着行版本控制可能是读写问题的解决方案。在step4中,使用行版本控制,数据库应该能够检测到它试图更改自step2中读取后版本已经更改的行。但我的实验证明这不是行为。将数据库的ReadCommited隔离和READ_COMMITTED_SNAPSHO设置为ON后,step4成功地将状态更新为state。

我的问题是,除了隔离级别可序列化之外,对于上面描述的读和写问题,还有其他数据库级别的解决方案吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-25 10:39:26

SQL server中的行版本控制是(这与其他数据库中的多版本并发控制MVCC的工作方式相同)--对于每一个被更改的行,它都维护一个单独的版本,以便如果存在对该行的读取请求--它使用该版本而不是引用尚未提交的行。这是一种更好的实现并发性的方法,即读取,然后不需要锁,因此在所有主要数据库中都实现了锁。现在,您可以看到为什么使用行版本控制(具有基于语句的或事务级的读取一致性)只为您提供一致的读取(在尚未提交的事务开始更改之前使用数据版本)。

如果您要从纯数据库端寻找解决方案,我认为可序列化的隔离级别是最好的。假设不会有很多事务同时处理同一数据行,那么保持锁的时间可能会很短。

另一种解决方案是使用表中的version列使用乐观并发控制。后面的事务将在update子句中具有"where version =1“,该子句将返回0行更新,因为第一个事务已经将版本增加到2。这可以被视为应用程序端的逻辑错误,并相应地传播消息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56747517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档