架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 22442|回复: 4

[资料] 处理并发Timestamp和ConcurrencyCheck区别

[复制链接]
发表于 2017-4-8 00:10:50 | 显示全部楼层 |阅读模式
QQ截图20170407234343.jpg

作者 www.itsvse.com @小渣渣 !
插入基础数据成功!
测试ConcurrencyCheck特性完成
更新成功!备注1
更新异常!备注2,异常信息!Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.

测试Timestamp和ConcurrencyCheck区别
UpdateTab1更新成功!名字1
UpdateTab2更新成功!名字1
UpdateTab2更新异常!名字2,异常信息!Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions.
UpdateTab1更新成功!名字2

【TimeStamp】
TimeStamp特性可以应用到领域类中,只有一个字节数组的属性上面,这个特性,给列设定的是tiemStamp类型。在并发的检查中,Code-First会自动使用这个TimeStamp类型的字段。

【ConcurrencyCheck】
ConcurrencyCheck特性可以应用到领域类的属性中。当EF执行更新操作的时候,Code-First将列的值放在where条件语句中,你可以使用这个CurrencyCheck特性,使用已经存在的列做并发检查,而不是使用单独的TimeStamp列来做并发检查。

我们首先新建一个上下文对象,来演示Timestamp和ConcurrencyCheck在并发处理中的区别!

下面是上下文的代码:




我们看一下数据库的列,如下:

QQ截图20170407234748.jpg

我们会发现,tab1和tab2都有Id、Name、Remark列,tab2比tab1多RowVersion列。

先附上测试代码:



【ConcurrencyCheck原理】

QQ截图20170407234933.jpg

我们在Tab1的Remark属性上面加上了ConcurrencyCheck特性,


我们在同时更新同一条数据的Name属性值的时候,没有抛出异常!


生成sql语句:


exec sp_executesql N'UPDATE [dbo].[Tab1]
SET [Name] = @0
WHERE (([Id] = @1) AND ([Remark] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'名字1',@1=1,@2=N'备注1'
exec sp_executesql N'UPDATE [dbo].[Tab1]
SET [Name] = @0
WHERE (([Id] = @1) AND ([Remark] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'名字2',@1=1,@2=N'备注1'

我们在同时更新同一条数据的Remark属性值的时候,抛出了异常!

生成sql语句:

exec sp_executesql N'UPDATE [dbo].[Tab1]
SET [Remark] = @0
WHERE (([Id] = @1) AND ([Remark] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'备注1',@1=1,@2=N'备注'
exec sp_executesql N'UPDATE [dbo].[Tab1]
SET [Remark] = @0
WHERE (([Id] = @1) AND ([Remark] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'备注2',@1=1,@2=N'备注'

我们可以,发现,同时取同一条Id为1的数据,都取到了Remark属性的值,在更新Remark属性的时候,都用Remark作为更新条件,

第一条sql语句可以更新成功,然后把Remark改成了“备注1”,在执行更新第二条sql语句的时候,会更新失败,因为Remark的值已经改变。

【Timestamp原理】

我们Tab2添加了一个RowVersion的属性(名字可以随便取),并添加了Timestamp的特性!!!

QQ截图20170408000212.jpg

我们在同时更新同一条数据的Name值的时候,第一条更新成功,第二条更新失败,并且抛出异常,我们来看一下生成的sql代码!

exec sp_executesql N'UPDATE [dbo].[Tab2]
SET [Name] = @0
WHERE ((([Id] = @1) AND ([RowVersion] = @2)) AND ([Remark] = @3))
SELECT [RowVersion]
FROM [dbo].[Tab2]
WHERE @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'名字1',@1=1,@2=0x00000000000007D1,@3=N'备注'
exec sp_executesql N'UPDATE [dbo].[Tab2]
SET [Name] = @0
WHERE ((([Id] = @1) AND ([RowVersion] = @2)) AND ([Remark] = @3))
SELECT [RowVersion]
FROM [dbo].[Tab2]
WHERE @@ROWCOUNT > 0 AND [Id] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8),@3 nvarchar(max) ',@0=N'名字2',@1=1,@2=0x00000000000007D1,@3=N'备注'

在执行第二条sql语句的时候,因为,已经找不到where条件的数据,所以更新失败,抛出异常!!!

因为,第一条sql语句执行成功之后,RowVersion的值会发生改变,如下图:

QQ截图20170408000706.jpg

QQ截图20170408001015.jpg

RowsVersion就是timestamp

丢失更新的解决方法   

丢失更新概念:当用户同时修改一行数据,他们先读取数据,放在前端进行修改,当修改后,再提交数据,这样最后提交的数据会覆盖先前提交的数据,这样就造成了丢失更新。

长话短说,介绍防止丢失更新的方法:

使用RowsVersion时间戳。

每次更新的时候,mssql都会自动的更新rowversion的值,若一行在读前与更新前的值前后不一致,就说明有其他的事务更新了此列,这样就可以不更新此列,从而防止了丢失更新的情况。



最后,附上源代码:
CodeFirstDemo.rar (4.94 KB, 下载次数: 13)




上一篇:nhibernate native 主键生成策略
下一篇:EF6 用Database.BeginTransaction管理事务
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-3-22 11:51:38 | 显示全部楼层
辛苦了,非常好的帖子
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2023-11-1 20:42:15 | 显示全部楼层
EF 并发异常 DbUpdateConcurrencyException 重新查询返回缓存值
https://www.itsvse.com/thread-10692-1-1.html
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
 楼主| 发表于 2023-12-27 19:54:01 | 显示全部楼层
EF Core 乐观锁 rowversion 生成的迁移语句




码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2024-4-24 21:23

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表