[英]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.