我創建了一個集成測試來驗證存儲庫是否正確處理併發。如果我在沒有TransactionScope的情況下運行測試,一切都按預期運行,但是如果我將測試包裝在TransactionScope中,則會出現一個錯誤,提示突然需要分佈式事務(這導致我相信存在第二個事務正在創建)。下面是測試:是否會在TransactionScope中創建隱式事務?
[Test]
public void Commit_ItemToCommitContainsStaleData_ThrowsStaleObjectStateException()
{
using (new TransactionScope())
{
// arrange
RootUnitOfWorkFactory factory = CreateUnitOfWorkFactory();
const int Id = 1;
WorkItemRepository firstRepository = new WorkItemRepository(factory);
WorkItem itemToChange = WorkItem.Create(Id);
firstRepository.Commit(itemToChange);
WorkItemRepository secondRepository = new WorkItemRepository(factory);
WorkItem copyOfItemToChange = secondRepository.Get(Id);
// act
copyOfItemToChange.ChangeDescription("A");
secondRepository.Commit(copyOfItemToChange);
itemToChange.ChangeDescription("B");
// assert
Assert.Throws<StaleObjectStateException>(() => firstRepository.Commit(itemToChange));
}
}
這是錯誤堆棧的底部:
失敗:NHibernate.Exceptions.GenericADOException:無法加載的實體:[TfsTimeMachine.Domain.WorkItem#1] [SQL :SELECT workitem0_.Id as Id1_0_,workitem0_.LastChanged as LastChan2_1_0_,workitem0_.Description as Descript3_1_0_ FROM [WorkItem] workitem0_ WHERE workitem0_.Id =?] ----> System.Data.SqlClient.SqlException:服務器'ADM4200上的MSDTC \ SQLEXPRESS'不可用。 NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session,Object id,IType identifierType,Object optionalObject,String optionalEntityName,Object optionalIdentifier,IEntityPersister persister)中的 。
我正在運行NUnit 2.1,所以有人可以告訴我,如果在查詢數據之前沒有session.BeginTransaction(),Nhibernate是否創建隱式事務,無論TransactionScope中運行的會話如何?
是的,你是正確的。所以答案是否定的,Nhibernate不會創建隱式事務。這會失敗,因爲兩個不同的ADO.net連接會登錄到同一事務,所以第二個存儲庫上的get請求會導致錯誤。現在我只需要控制一個交易範圍內的會話連接(在我的情況下不需要遠程轉換)來使其工作 – Marius 2009-12-31 08:48:17