假设我有以下代码将用户插入 MVC 应用程序中的 MS Dynamics:
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 的主要性能问题。
显然,用户得到了巨大的延迟,并且经常三次点击触发这段代码的按钮。
问题是,在 .SaveChanges() 在第一个请求中完成之前,.Count() 在不同的 Http 请求中同时触发。结果,我们看到了具有相同电子邮件地址的联系人。
虽然我已经从客户端添加了一个修复程序,但我想看看这是否也可以在服务器端完成。
什么是使这个线程安全的好策略?
编辑:
虽然在 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;
}
}
它通过了我的单元测试,似乎没有任何问题。