使用新事务时,RavenDB因ConcurrencyException而失败

时间:2014-07-04 09:20:10

标签: ravendb

此代码始终因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

1 个答案:

答案 0 :(得分:1)

由于没有其他人回答,我最好自己试一试。

事实证明这是一个人为错误。由于我们的IOC容器配置错误,DataAccess.NewOpenSession一直给我相同的Session(跨越其他测试)。换句话说,Raven按预期工作:)

在我发现这一点之前,我还尝试使用TransactionScopeOption.Suppress而不是RequiresNew。这也有效。然后我必须确保无论我在抑制范围内做了什么都不会失败。在我的案例中,这是一个有效的选择。