我创建了一个集成测试来验证存储库是否正确处理并发。如果我在没有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