Транзакции в MongoDB

Имеется коллекция в MongoDB в которой хранятся данные об обработке данных expressjs сервером .

Так как обработка происходит асинхронно, а целостность этих данных очень важна я пришел к использованию транзакций. Драйвером MongoDB в моем случае выступает mongoose. Код примерно таков (он упрощен и не имеет некоторых валидаций):

const express = require('express');
const mongoose = require('mongoose');
const app = express();
const Schema = new mongoose.Schema({
    id: Number,
    name: String
}, {
    autoCreate: true
});
const Data = mongoose.model('Data', Schema );
app.get('/', function (req, res) {
    if(req.query.id && req.query.name) {
        //Начало сессии
        const session = await Data.startSession();
        //Запуск транзакции
        session.startTransaction();
        try {
            //Поиск уже существующей записи
            const exits = await Data.findOne({id: req.query.id, name: req.query.name}).session(session);
            
            if (exits === null) {//Если ее нет, то создаем
                await Data({id: req.query.id, name: req.query.name}).save({session});
            }
            await session.commitTransaction();
        } catch (error) {
            await session.abortTransaction();
            session.endSession();
            console.log(error)
        } finally {
            session.endSession();
        }
    }
    res.send('ok')
})

app.listen(3000)

Гарантирует ли такой подход исключение ситуации с асинхронным выполнением двух транзакций когда поступает 2 одинаковых запроса и когда (как это было бы при операциях без транзакции):

  1. Запрос #1 Делает запрос на проверку существования | Запрос #2 уже ранее сделал запрос, но не сделал insert
  2. Запрос #1 Проверил на существование и понял что записи еще нет | Запрос #2 Все еще не сделал insert
  3. Запрос #1 Делает insert | Запрос #2 Делает insert
  4. В базе имеется 2 экземпляра одной записи

Если подход с транзакциями это исключит, тогда вопрос. Транзакции выполняются по очереди и до завершения активной транзакции коллекция не может быть модифицирована из вне?

Если одна транзакция выполнится, получается что вторая так же выполнится успешно проверив на существование, и так как запись будет уже добавлена первой транзакцией, то просто не добавит новую?

Обязательно ли делать session.commitTransaction(); если я не делал изменений в базе и только делал из нее выборки (случай когда exits !== null)


Ответы (0 шт):