说我有下面的代码,接入用户为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