在我的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