簡體   English   中英

實體框架DbContext和線程安全

[英]Entity Framework DbContext and thread safety

我需要在單個事務中更新我的數據庫中的幾個表,並且我讀到使用DbContext.SaveChanges應該是這樣做的方法。

但是我還讀到DbContext的生命周期應該盡可能短,因為它會隨着時間的推移而增加,因為它會加載更多的實體。

另外我讀到為了使其成為線程安全的,每個動作都應該有自己的DbContext

我是否應該為每個要更改的表都有一個DbContext並在每個DbContext上調用SaveChanges 最后一次SaveChanges調用不會覆蓋先前調用的更改嗎?

最好的方法是什么? (我需要這個網站)

簡單的方法是,每個請求都有一個DbContext,ASP.NET MVC完成所有線程安全,ASP.NET MVC中的每個控制器實例都是針對每個請求進行隔離的,您不必擔心競爭條件。 只要您不使用單個DbContext創建線程並且只是在動作方法中進行數據轉換,就不會有任何問題。

基本上DbContext什么都不做,它只是將SQL查詢排隊到目標數據庫,它是處理多線程,競爭條件的數據庫。 為了保護您的數據,您應該使用事務並在數據庫中添加驗證以確保它們得到正確保存

public abstract class DbContextController : Controller{

    public AppDbContext  DB { get; private set;}

    public DbContextController(){
        DB = new AppDbContext();
    }

    protected override void OnDisposing(bool disposing){
        DB.Dispose();
    }

}

如果從DbContextController繼承任何類並在控制器的整個生命周期中使用DB,則不會有任何問題。

public ActionResult ProcessProducts(){
    foreach(var p in DB.Products){
       p.Processed = true;
       foreach(var order in p.Orders){
          order.Processed = true;
       }
    }
    DB.SaveChanges();
}

但是,如果您使用以下示例中的任何線程,

public ActionResult ProcessProducts(){
    Parallel.ForEach(DB.Products, p=>{
         p.Processed = true;
         // this fails, as p.Orders query is fired
         // from same DbContext in multiple threads
         foreach(var order in p.Orders){
             order.Processed = true;
         }
    });
    DB.SaveChanges(); 
}

實體框架不是線程安全的 每個請求實例化一個MVC控制器 因此,如果您為每個請求使用一個DbContext,只要您不在控制器操作中手動生成線程(您不應該這樣做),您就是安全的。

現在,如果您的應用程序中有並發性 ,就像預訂系統中有多個用戶可以訪問可用的相同稀缺資源(如票證),您必須自己實現邏輯。 無論如何,沒有線程安全可以幫助你。

這就是為什么你被要求在評論中提供代碼的原因,因為解釋線程安全通常過於寬泛,可能不適用於你的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM