EF CORE 使用排他锁 干货 方法 悲观锁 entity framework 悲观锁

这几天在升级.NET CORE版本,结果发现坑太大了,最后还是退级了。。原因是作为长期支持版本的3.1居然一大堆bug 官方没有解决。。

查询了国内官方的基本没人讨论过EF怎么加悲观锁,很是蛋疼,去谷歌搜了一圈,把资料搬回来了。

废话不多说,一般来说EF是用不了排他锁的,也就是悲观锁,但是可以用曲线救国的办法实现,这对并发处理是至关重要的,不知道为什么官方居然不支持。

首先我用的数据库是mysql,引擎必须要InnoDB才支持行级锁,如果你的引擎不是可以用这个修改

alter table 表名 engine=InnoDB;

每个表的引擎都可以是单独不一样的,很多人使用锁失败可能是一开始就用不对引擎,以为全局引擎是lnnoDB就以为表也是这个引擎了,其实不是,查看办法可以用mysql for Navicat 设计-选项自己看看。

要加锁的话必须在查询背后添加 for update,这样查询的时候就会开始等待

for update 只能用来等待加了for update 的,如果你的select 没有加for update ,那也是等于无锁,这个网上很多解释了,反正你想等待,那就得一起加上for update ,否则有一个没加的,那那个就可以直接查询到结果而不会等待。不赘述了,网上解释一大堆。

好了,在EF CORE使用,那就引用一个事务,套个框框即可

 

复制代码
using (var context = new DatabaseContext())
    {
//套上事务
using (IDbContextTransaction transaction = context.Database.BeginTransaction()) { string sqlQuery = "select * from 表名 where id =1 for update"; var info = context.表名.FromSql(sqlQuery).FirstOrDefault();

//这个时候查询已经被锁住了,可以做你要的事了
//TODO

//完成提交事务即可
transaction.Commit();
} }

记得用using哦,这样如果操作失败,EF会自动调用
transaction.Rollback()进行数据回滚,不会造成脏数据~一个事务就是一个最小的操作单元,要么都成功要么都失败!

复制代码

 

如果要锁住行,这个查询条件一定要是可以索引的,或者是主键,否则会锁住整个表,非常不好。

关键点:

1:所有需要等待的语句必须都使用for update

2:表的引擎一定要是InnoDB,而不是全局引擎

3:查询条件一定要加索引,或者主键

这样基本就ok了,我现在还是在用EFCORE1.0,升级成3.0后就没有FromSql了,变成FromSqlRaw,为什么不升级3.0,是因为官方存在内存泄露,顶级投影被削弱,重要的关键根本没改进,还不如不要,折腾了我一整个春节。。有感兴趣的我再说吧。。

 

posted @   MayBreath  阅读(4164)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示