說我有下面的代碼,接入用戶爲MS動態的MVC應用程序:戰略線程安全的數據庫訪問
public bool CreateContact(string email)
{
if (crm.contacts.Count(x => x.Email == email) > 0)
return false; //Email already exist in the Crm. Skip
var contact = new contact {Email = email};
crm.AddTocontacts(contact);
crm.SaveChanges();
return true;
}
它的偉大工程從同一個電子郵件地址登錄停止用戶,直到最近當我們遇到Dynamics的主要性能問題時。
顯然,用戶正在獲得巨大的延遲,並且經常三次點擊觸發這段代碼的按鈕。
問題是,.Count()在不同的Http Requests中同時觸發.SaveChanges()在第一個Request中完成。因此,我們看到有相同電子郵件地址的聯繫人。
雖然我已經從客戶端添加了一個修復程序,但我想看看這是否也可以在服務器端完成。
什麼是一個好的策略,使這個線程安全?
編輯:
雖然對CRM增加一個約束是最好的解決方案,許多建議在這裏,是因爲重複已經在CRM存在,我不能實施這些解決方案在目前發現這個問題很久以前。顯然有不止一個應用程序與CRM進行對話。
與鎖和線程的經驗非常少,我最終做了以下內容:
internal static class ContactLock
{
internal static readonly object Locker = new object();
}
public bool CreateContact(string email)
{
lock(ContactLock.Locker)
{
if (crm.contacts.Any(x => x.Email == email))
return false; //Email already exist in the Crm. Skip
var contact = new contact {Email = email};
crm.AddTocontacts(contact);
crm.SaveChanges();
return true;
}
}
它通過我的單元測試,似乎是工作沒有任何問題。
這個工作時禁用按鈕? – 2012-07-24 21:15:19
奧斯汀,是的,我已經在客戶端做到了。但我想看看我是否也可以從服務器上做到這一點。 – 2012-07-24 21:32:19
對於a)意圖和b)可能的優化,優先選擇'.Any(x => x.Email == email)'Count'(x => x.Email == email)> 0'。 – 2012-07-24 21:54:37