zoukankan      html  css  js  c++  java
  • 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,是因为官方存在内存泄露,顶级投影被削弱,重要的关键根本没改进,还不如不要,折腾了我一整个春节。。有感兴趣的我再说吧。。

  • 相关阅读:
    阶梯式测试
    websocket协议
    性能指标
    环境变量
    解密断言+参数写入文本
    将参数进行URL编码
    日志级别
    对返回结果进行断言
    python小题目:循环/函数
    如果使用JSON提取器 和正则提取器
  • 原文地址:https://www.cnblogs.com/maybreath/p/12254454.html
Copyright © 2011-2022 走看看