簡體   English   中英

ASP.NET | 實體框架,競爭條件

[英]ASP.NET | Entity Framework, race condition

我有一個Web應用程序,允許用戶喜歡的項目。 每件物品都有他喜歡的總物品。

當許多用戶同時喜歡同一個項目時會出現問題,然后我在SQL中收到錯誤的值(由競爭條件引起)。

作為一個臨時解決方案,我在控制器構造函數中創建了一個工作線程,它對一個隊列起作用,當一個像/不喜歡請求的項目正在接收時,我正在排隊這個請求。 工作線程正在對值進行dequeing並更新將itemid映射到totalcount的字典。

然后,工作線程每隔一分鍾更新一次數據庫,並顯示結果。

附帶問題: context.SaveChanges()只保存對象中更改的內容嗎? 或者它是否保存了對象的所有屬性?

我覺得這個解決方案不是正確的,處理這樣一個問題的最佳方法是什么?

您可以使用RepeatableRead事務范圍在讀取和寫入時鎖定數據:

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
    ...
    context.SaveChanges();
    scope.Complete();
}

實體框架跟蹤實體字段更改並生成SQL代碼以僅更新已修改的代碼。 您可以明確指定只想更新一個實體屬性並忽略其他更改:

context.Entry(entity).State = EntityState.Unchanged;
context.Entry(entity)
        .Property(c => c.entityField).IsModified = true;

將對象附加到上下文中時它也很有用:

context.Attach(entity);
context.Entry(entity)
        .Property(c => c.entityField).IsModified = true;

因為Attach將實體及其屬性放入Unchanged狀態的上下文中。

對於性能和並發問題,使用ExecuteSqlCommand更好:

string sql = "UPDATE Table SET LikeCount = LikeCount+1 WHERE Id={0}";
using (var context = new BloggingContext()) 
{ 
    context.Database.ExecuteSqlCommand( sql, new SqlParameter("@Id", id)); 
}

暫無
暫無

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

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