在我的EF4程序中,我有一个申请人和应用程序表。该程序的多个实例会定期运行,以根据某些业务逻辑为应用程序创建应用程序。在申请表中,我不能为申请人提供多个提交/正在提交的记录。parallel.invoke事务范围实体框架
因此,这里的一块,它检查是否有一个提交/ BeingSubmitted应用程序,并将其插入代码。它在申请人列表的foreach循环中运行。
public Application SaveApplication(Int32 applicantId)
{
using (TransactionScope txScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
if (ApplicantHasPendingApplication(applicantId))
return null;
Application app = null;
try
{
app = new Application()
{
// Create the object...
};
_unitOfWork.DisclosureApplications.Add(app);
_unitOfWork.Commit();
_unitOfWork.Refresh(app); // We save and refresh it to get the Id.
txScope.Complete();
}
catch (UpdateException ex)
{
// We get an Update exception here when multiple instances tries to insert Application.
}
return app;
}
}
上面的一段代码防止插入重复记录,除了在运行程序的多个实例时抛出UpdateException的事实。如果我吞下那个异常并继续进行,那么一切都很好。
然而,我试图测试/上述并行代码运行,但它在数据库中插入重复的记录。
Parallel.Invoke(
() => CreateApplications("Parallel Instance 1"),
() => CreateApplications("Parallel Instance 2"));
private void CreateApplications(String dummyInstanceName)
{
var unitOfWork = new SqlUnitOfWork();
var applicants = unitOfWork.Applicants.FindAll().Take(100).ToList();
var facade = new ProviderFacade(unitOfWork, new Log4NetLogger(dummyInstanceName));
foreach (Applicant applicant in applicants)
{
facade.ApplicationProvider.SaveApplication(applicant.applicantID);
}
}
在上面的一段代码中,它抛出UpdateException并为申请人插入多个Application行。
请注意,该表只有一个代理主键,没有其他唯一性约束。
我的问题是:为什么TransactionScope的由Parallel.Invoke运行它插入重复行,但不是当我关火程序的多个实例?实现它的方法是什么?
更新:SqlUnitOfWork的构造函数是
public SqlUnitOfWork()
{
_context = new MyEntities();
}
由EF产生MyEntities的构造函数 -
public const string ConnectionString = "name=Entities";
public const string ContainerName = "Entities";
public TPIEntities() : base(ConnectionString, ContainerName)
{
this.ContextOptions.LazyLoadingEnabled = true;
}
感谢。
当您调用facade.ApplicationProvider.SaveApplication时,正在使用什么_unitOfWork?我没有看到在CreateApplications中创建的SqlUnitOfWork如何通过那里。如果您的两个CreateApplications实例最终有效使用相同的SqlUnitOfWork,那可能与您的问题有关。 – 2012-07-12 09:50:15
请参阅更新。还添加了创建外观的线。当我在CreateApplications中创建一个新的SqlUnitOfWork时,在并行方法调用中使用相同UnitOfWork的可能性是什么? (我是并行编程的新手。) – user1520015 2012-07-12 10:13:39