此代码始终因ConcurrencyException而失败:
[Test]
public void EventOrderingCode_Fails_WithConcurrencyException()
{
Guid id = Guid.NewGuid();
using (var scope1 = new TransactionScope())
using (var session = DataAccess.NewOpenSession)
{
session.Advanced.UseOptimisticConcurrency = true;
session.Advanced.AllowNonAuthoritativeInformation = false;
var ent1 = new CTEntity
{
Id = id,
Name = "George"
};
using (var scope2 = new TransactionScope(TransactionScopeOption.RequiresNew))
{
session.Store(ent1);
session.SaveChanges();
scope2.Complete();
}
var ent2 = session.Load<CTEntity>(id);
ent2.Name = "Gina";
session.SaveChanges();
scope1.Complete();
}
}
它在最后一次会话失败.SaveChanges。声明它正在使用NonCurrent etag。如果我对scope2使用Required而不是RequiresNew - 即使用相同的Transaction。它有效。
现在,因为我加载了实体(ent2),它应该使用最新的Etag,除非这是我正在使用的scope1附加的一些缓存值(但我已禁用缓存)。所以我不明白为什么会失败。
我真的需要这个设置。在生产代码中,外部TransactionScope由NServiceBus创建,内部用于控制事件排序的一个方面。它不能是相同的交易。
我也需要乐观并发 - 如果其他线程同时使用该实体。
BTW:这是使用Raven 2.0.3.0
答案 0 :(得分:1)
由于没有其他人回答,我最好自己试一试。
事实证明这是一个人为错误。由于我们的IOC容器配置错误,DataAccess.NewOpenSession一直给我相同的Session(跨越其他测试)。换句话说,Raven按预期工作:)
在我发现这一点之前,我还尝试使用TransactionScopeOption.Suppress而不是RequiresNew。这也有效。然后我必须确保无论我在抑制范围内做了什么都不会失败。在我的案例中,这是一个有效的选择。