首页 > 编程学习 > EFCore 悲观锁 和 乐观锁

EFCore 悲观锁 和 乐观锁

发布时间:2022/8/27 3:06:28
乐观并发控制
并发令牌 IsConcurrencyToken() * 单个字段设置并发

经典例子就是两个人同时执行了抢购业务 Update是同时执行的,这就导致后面的会覆盖前面的,导致业务出现问题!
原理就是在 update的表中 Owner = 旧值
1、我们需要 只需要让EFCore在 code first下配置实体 设置一下Owner 字段为 IsConcurrencyToken() 设置为并发令牌
2、例如:“builder.Property(x=>x.Owner).IsConcurrencyToken()”
3、在保存的时候进行 SaveChangesAsync() 添加
catch(DbUpdateConcurrencyException ex) 进行捕获
例如:

try{
		await ctx.SaveChangesAsync();
		Console.WriteLine("抢到手了");
	}
	catch (DbUpdateConcurrencyException ex)
	{
		var entry = ex.Entries.First();
		var dbValues = await entry.GetDatabaseValuesAsync();
		string newOwner = dbValues.GetValue<string>(nameof(House.Owner));
		Console.WriteLine($"并发冲突,被{newOwner}提前抢走了");
	}
效果图

image

测试

image

生成的SQL

可以看到 我们定义的并发令牌字段 IsConcurrencyToken 会在 Update And 带上这个字段 进行查询
可能比较抽象 这里我们可以用具体的sql 语句进行分析
例如:
第一次执行的 Update T_houses Set Owner= 'tom' where Id =1 And Owner = '' 注意:此时Owner 是没有值的 所以受影响行数为 1

第二次执行的 Update T_houses Set Owner= 'tom' where Id =1 And Owner = ''
注意:此时Owner 第一次执行后Owner已经被赋值了,所以此时 where Id =1 的Owner是有值的,所以where条件是不满足 受影响行数为 0
image

RowVersion * 多字段设置并发
Copyright © 2010-2022 mfbz.cn 版权所有 |关于我们| 联系方式|豫ICP备15888888号