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(); 
       }

    }可以加个try catch,如果失败就使用回滚 transaction.Rollback();完美!

 

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

关键点:

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

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

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

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

 

来源:https://www.cnblogs.com/maybreath/p/12254454.html