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,是因為官方存在內存泄露,頂級投影被削弱,重要的關鍵根本沒改進,還不如不要,折騰了我一整個春節。。有感興趣的我再說吧。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM