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,是因为官方存在内存泄露,顶级投影被削弱,重要的关键根本没改进,还不如不要,折腾了我一整个春节。。有感兴趣的我再说吧。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库