EF/EFCore 中RowVersion与ConcurrencyToken的比较

Posted qianxingmu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF/EFCore 中RowVersion与ConcurrencyToken的比较相关的知识,希望对你有一定的参考价值。

最近我被问到了一个相当好的关于EFCore的问题(虽然一般来说它并不是一个数据库的概念):我应该使用RowVersion 还是ConcurrencyToken作为乐观并发?

我觉得答案是其依赖于,更明确的说,你知道它们两者之间的区别及不足之处么吗?

让我们往回倒一点,以准确的来说,什么是Concurrency Tokens来作为开始,然后是RowVersion,最后我们来看看它们是如何比较的。

什么是Concurrency Token

一个concurrency token 是一个每次一条数据库记录被更新时候都会进行检查的一个值。通过检查,我的意思更明确的说,就是已存在的值会被用作SQL语句的一部分,因此如果其在你这儿发生了变化,UPDATE语句便会失败。如果两个用户同时更新同一条记录,那么这种情况便会发生。

以非常粗糙的流程图形式表现如下:

技术图片

 

 用户B和用户A同时更新同一条记录时,最糟糕的情形他会将用户A的更新稀里糊涂的覆盖掉,就算是最好的情况,用户BY将用自己读取到的知识来对数据库所做的更新也会被用户A覆盖掉。

concurrency token 通过简单检查包含在最初读取中的信息是否还在(写入时)来对付这种情况。我们假设有一个叫做“User”的数据库表,其看起来像是这样:

Id		int
FirstName	nvarchar(max)
LastName	nvarchar(max)
Version		int

通常一个没有带concurrency token的SQL Update语句看起来像是这样:

UPDATE User
SET FirstName = ‘Wade‘
WHERE Id = 1

但是如果我们用Version列作为concurrency token,它或许看起来像是这样:

UPDATE User
SET FirstName = ‘Wade‘, Version = Version + 1
WHERE Id = 1 AND Version = 1

在我们的Where语句中Version的值是我们读取最初的数据时获取到的值。在这种方式下,如果有个人在我们读取并更新数据的时候更新了这个记录,Version值便不会匹配,从而导致我们的更新失败。

以上是关于EF/EFCore 中RowVersion与ConcurrencyToken的比较的主要内容,如果未能解决你的问题,请参考以下文章

EF Core中通过Fluent API配置多对多关系

EF Core中通过Fluent API配置多对多关系

EF Core中通过Fluent API配置多对多关系

如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?

EF4 与 SQL Compact 4,rowversion 在保存时不更新

[小技巧]EF Core中如何获取上下文中操作过的实体