Mongo DB с C# - документ добавляется независимо от транзакции
Я пытаюсь протестировать недавно поддерживаемые транзакции в БД Mongo на простом примере, который я написал. Я использую Mongo DB версии 4.0.5 с драйвером версии 2.8.1. Это только основной экземпляр без осколков / реплик.
Я должен пропустить что-то основное в следующем коде. Я создаю клиент Mongo, сессию и базу данных, затем запускаю транзакцию, добавляю документ и отменяю транзакцию. После этого кода я не ожидаю ничего изменить в базе данных, но документ добавлен. При отладке я также вижу документ сразу после InsertOne()
с помощью Robo 3T (графический клиент Mongo).
Есть идеи, что мне не хватает?
var client = new MongoClient("mongodb://localhost:27017");
var session = client.StartSession();
var database = session.Client.GetDatabase("myDatabase", new MongoDatabaseSettings
{
GuidRepresentation = GuidRepresentation.Standard,
ReadPreference = ReadPreference.Primary,
WriteConcern = new WriteConcern(1,
new MongoDB.Driver.Optional<TimeSpan?>(TimeSpan.FromSeconds(30))),
});
var entities = database.GetCollection<MyEntity>("test");
session.StartTransaction();
// After this line I can already see the document in the db collection using Mongo client GUI (Robo 3T), although I expect not to see it until committing
entities.InsertOne(new MyEntity { Name = "Entity" });
// This does not have any effect
session.AbortTransaction();
Редактировать:
Возможно запустить MongoDB как набор реплик из 1 узла, хотя я не уверен, в чем разница между автономным набором и набором реплик из 1 узла. Смотрите мой пост ниже.
В любом случае, чтобы использовать запущенную транзакцию, код вставки должен получить сеанс в качестве параметра:
entities.InsertOne(session, new MyEntity { Name = "Entity" });
С этими 2 изменениями теперь работает транзакция.
2 ответа
По сути, это свойство самого MongoDB. (Подробнее здесь и здесь)
Транзакции доступны только в настройках набора реплик
Почему он не доступен для отдельных экземпляров?
С помощью вложенных документов и массивов базы данных документов (MongoDB) позволяют иерархически объединять связанные данные в единой структуре данных. Документ может быть обновлен с помощью атомарной операции, предоставляя ему те же гарантии целостности данных, что и многотабличные транзакции в реляционной базе данных.
Я нашел решение, хотя не уверен, каковы последствия, может быть, кто-то может указать на это: кажется, что возможно использовать Mongo DB как набор реплик с 1 узлом (вместо автономного), просто добавив следующее в mongod. CFG файл:
replication:
replSetName: rs1
Кроме того, благодаря следующей ссылке код должен использовать правильную перегрузку InsertOne()
который получает сессию в качестве первого параметра (см. редактирование исходного сообщения):