RavenDB плохо взаимодействует с Transaction Scope.

У меня есть следующий тестовый пример, который я ожидаю пройти. Но он не проходит с RavenDB.
Если я создаю точно такой же тест с MsSql, он проходит.

        var connectionString = "Url=http://localhost:8080";
        var store = new DocumentStore();
        store.ParseConnectionString(connectionString);
        store.Initialize();
        using (var scope = new TransactionScope())
        using (var session = store.OpenSession())
        {
            session.Store(dog);
            session.SaveChanges();

            var dogs = session.Query<Dog>().Customize(x => x.WaitForNonStaleResults()).ToList();
            Assert.AreEqual(1, dogs.Count);
            scope.Complete();
        }

Я пытаюсь написать некоторый код, который работает одинаково, независимо от того, какую базу данных я выбираю, и это всего лишь пример тестового примера, который я пытаюсь пройти.

Я пробовал разные вещи, такие как ожидание неустаревших результатов и разрешение неаутентитивных ... что-то и т. Д. И т. Д.


person Quintonn    schedule 13.07.2014    source источник
comment
Поэтому я не могу сделать запрос до завершения транзакции, хорошо (пока). Я создал другой тест, в котором я делаю вызов RavenDB и вызов MsSql внутри одной и той же транзакции. Но выдает исключение. Вот ссылка на этот вопрос: stackoverflow.com/questions/24828095/   -  person Quintonn    schedule 18.07.2014


Ответы (2)


Чтобы расширить ответ Айенде, в отличие от MSSQL, хранилище документов (операции хранения/загрузки) отделено от хранилища индексов и является единственным, что КИСЛОТА. Хранилище индексов не является транзакционным и обновляется асинхронно после завершения обновления хранилища документов. В этом случае используется распределенная (DTC) транзакция после фиксации транзакции. Это предусмотрено дизайном.

Поэтому, хотя ваш код не будет работать так, как вы предполагали, это должно:

var connectionString = "Url=http://localhost:8080";
var store = new DocumentStore();
store.ParseConnectionString(connectionString);
store.Initialize();
using (var scope = new TransactionScope())
using (var session = store.OpenSession())
{
    Dog dog = new Dog { Id = "dogs/1" };
    session.Store(dog);
    session.SaveChanges();

    var dog2 = session.Load<Dog>("dogs/1");
    Assert.AreEqual(dog, dog2);
    scope.Complete();
}

Вы даже можете использовать:

Dog[] dogs = session.Advanced.LoadStartingWith<Dog>("dogs");

Но все, что запрашивает данные из хранилища индексов (запрос), не вернется, потому что данные еще даже не были постоянно добавлены в хранилище транзакций, а тем более асинхронно отображены в хранилище индексов.

person David Boike    schedule 15.07.2014

В RavenDB, пока транзакция DTC не будет зафиксирована, данные не будут добавляться ни в какие индексы.

person Ayende Rahien    schedule 14.07.2014
comment
Есть ли способ заставить это работать? Как-нибудь вообще? - person Quintonn; 15.07.2014
comment
Вы не поняли истинной природы RavenDB. Данные и индексы не работают в одном потоке. Думайте об индексах как о кеш-таблицах в SQL. Когда вы изменяете данные, появляется триггер, который запускает обновление таблицы кеша данными. Это означает, что вы должны сначала зафиксировать данные (scope.complete), а затем дождаться обновления индекса. ofc, вы всегда можете просто выполнить session.load(), который всегда будет давать вам правильные данные - person Michael Kire Hansen; 10.09.2015
comment
Также обратите внимание, что вы можете выполнить session.load() для списка идентификаторов, а не только для одного идентификатора. - person Michael Kire Hansen; 10.09.2015