我在nHibernate上有一个竞争条件,它在我的数据库上创建了重复的条目。不幸的是,我无法在数据库上创建UNIQUE
索引,因此我想仅使用nHibernate方法来解决此错误。它是一个可能在Web场上运行的Web应用程序(因此我猜系统锁不应该解决问题)。简化的情况如下:
var current = UnitOfWorkManager.Instance.Current;
current.BeginTransaction(IsolationLevel.Serializable);
try {
var myEntity = MyFactory.MyEntityRepository.GetBy(product, company);
// race condition happens between the previous statement and Save() method.
if (myEntity == null)
{
myEntity = new MyEntity();
myEntity.Product = product;
myEntity.Company = company;
myEntity.Date = date;
myEntity.CurrentUser = currentUser;
myEntity.IsManual = true;
myEntity.Save();
}
else
{
myEntity.IsManual = false;
myEntity.Save();
}
current.CommitTransaction();
}
catch {
current.RollbackTransaction();
throw;
}
我是nHibernate的新手,所以也许我在这里缺少一些基础知识。我很感激任何反馈。 :)
答案 0 :(得分:1)
阅读nHibernate手册后,我认为如果subProjectToSupplier不为null,您的问题可能是第二次保存。因为nHibernate手册说“保存”会插入。
尝试SaveOrUpdate
答案 1 :(得分:0)
您应该将Save()
包装在一个交易中,理想情况下,您可以实施IUnitOfWork
等模式或使用SessionFactory
,例如:
using (var transaction = session.BeginTransaction()) {
myEntity = new MyEntity();
myEntity.Product = product;
myEntity.Company = company;
myEntity.Date = date;
myEntity.CurrentUser = currentUser;
myEntity.IsManual = true;
myEntity.Save();
transaction.Commit();
}
答案 2 :(得分:0)
好的,所以你在这里要求NHibernate解决方案。我不确定这是否可以100%解决你的问题,但试试这个。
在拦截器中你可以做到:
=====
其他解决方案是在服务器场(memcache)和跟踪您不希望重复的对象之间保持共享缓存。
PS:我可以多谈谈每一点。只要告诉我一些事情听起来像是你的解决方案