Такие читатели, как вы, помогают поддерживать MUO. Когда вы совершаете покупку по ссылкам на нашем сайте, мы можем получать партнерскую комиссию.

Создание готового веб-приложения требует от вас обеспечения его безопасности и масштабируемости.

Одна из самых важных вещей, которые нужно знать о базах данных, — это принцип ACID, который означает атомарность, непротиворечивость, изоляцию и надежность. Реляционные базы данных, такие как MySQL, изначально поддерживают транзакции ACID. Но MongoDB — это база данных NoSQL, которая по умолчанию не поддерживает транзакции ACID.

Как программист, вы должны знать, как ввести свойства ACID в свои базы данных MongoDB.

Что такое транзакции базы данных?

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

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

instagram viewer

Объяснение свойств ACID

Четыре свойства, составляющие принципы ACID:

  • атомарность это свойство, которое концептуализирует транзакции как небольшие единицы программы. Это означает, что все запросы либо выполняются успешно, либо вместе завершаются ошибкой.
  • Последовательность утверждает, что записи базы данных должны оставаться согласованными до и после каждой транзакции.
  • Изоляция гарантирует, что при одновременном выполнении нескольких транзакций одна не повлияет на другую.
  • Долговечность фокусируется на системных сбоях или ошибках. Это гарантирует, что совершенная транзакция не будет потеряна в случае сбоя системы. Это может включать методы, необходимые для автоматического восстановления данных из резервной копии после повторного запуска системы.

Как реализовать транзакции базы данных MongoDB в Node.js с помощью Mongoose

MongoDB с годами стала широко используемой технологией баз данных из-за его природа NoSQL и гибкая модель на основе документов. Он также предлагает вам возможность лучше организовать ваши данные и более гибко, чем в SQL или реляционных базах данных.

Чтобы реализовать транзакции базы данных в MongoDB, вы можете рассмотреть пример сценария в приложении со списком вакансий, где пользователь может опубликовать, обновить или удалить вакансию. Вот простой дизайн схемы базы данных для этого приложения:

Чтобы следовать этому разделу, требуются базовые знания программирования Node.js и MongoDB.

Транзакции не поддерживаются в автономных установках MongoDB. Вам нужно будет использовать Набор реплик MongoDB или сегментированный кластер MongoDB чтобы транзакции работали. Поэтому самый простой способ использования транзакций — это создать облачный экземпляр MongoDB (Атлас MongoDB). По умолчанию каждый экземпляр базы данных Atlas представляет собой набор реплик или сегментированный кластер.

Настроив рабочий проект Node.js и MongoDB, вы можете настроить подключение к базе данных Mongo в Node.js. Если вы еще этого не сделали, установите mongoose, запустив npm установить мангуста в вашем терминале.

Импортировать мангуста от 'мангуста'

пусть MONGO_URL = process.env. МОНГО_URL || 'URL-адрес вашей-монго-базы данных';

позволять связь;
константа подключитьДб = асинхронный () => {
пытаться {
Ждите mongoose.connect(MONGO_URL, {
использовать ньюурлпарсер: истинный,
использовать унифицированную топологию: истинный,
});

console.log("ПОДКЛЮЧЕН К БАЗЕ ДАННЫХ");
соединение = мангуст.соединение;
} ловить (ошибка) {
консоль.ошибка("СБОЙ ПОДКЛЮЧЕНИЯ К БАЗЕ ДАННЫХ!");
консоль.ошибка(ошибаться.сообщение);
процесс.Выход(1); // закрыть приложение, если соединение с базой данных не удалось
}
};

Вы должны сохранить соединение в переменной, чтобы вы могли использовать ее для инициирования транзакции позже в программе.

Вы можете реализовать коллекции пользователей и заданий следующим образом:

константа пользовательская схема = новый мангуста. Схема({
имя: Нить,
электронная почта: Нить,
рабочие места: [мангуста. Схема. Типы. идентификатор объекта]
});

константа схема работы = новый мангуста. Схема({
заголовок: Нить,
расположение: Нить,
зарплата: Нить,
плакат: мангуста.Схема.Типы.ObjectId
});

const userCollection = mongoose.model('пользователь', пользовательская схема);
константа jobCollection = mongoose.model('работа', схема работы);

Вы можете написать функцию для добавления пользователя в базу данных следующим образом:


константа создать пользователя = асинхронный (пользователь) => {
константа новый пользователь = Ждите userCollection.create (пользователь);
консоль.log("Пользователь добавлен в базу данных");
консоль.log (новый пользователь);
}

В приведенном ниже коде демонстрируется функция создания задания и добавления его в список заданий плаката с использованием транзакции базы данных.


константа создать задание = асинхронный (работа) => {
константа {userEmail, должность, местоположение, зарплата} = работа;

// получаем пользователя из БД
константа пользователь = Ждите userCollection.findOne({ электронная почта: электронная почта пользователя });

// начинаем транзакционную сессию
константа сеанс = Ждите соединение.startSession();

// запускаем все запросы к базе данных в блоке try-catch
пытаться {
Ждите сессия.startTransaction();

// создать задание
константа новая работа = Ждите jobCollection.create(
[
{
заголовок,
расположение,
зарплата,
постер: user._id,
},
],
{ сеанс }
);
консоль.log("Создано новый работа выполнена успешно!");
консоль.log (новая работа[0]);

// добавить вакансию в список опубликованных вакансий пользователей
константа идентификатор новой работы = новая работа[0]._идентификатор;
константа добавленопользователю = Ждите userCollection.findByIdAndUpdate(
ID пользователя,
{ $adToSet: { рабочие места: идентификатор новой работы } },
{ сеанс }
);

консоль.log("Вакансия успешно добавлена ​​в список вакансий пользователя");
консоль.log (добавленопользователю);

Ждите сеанс.commitTransaction();

консоль.log("Успешно проведена транзакция БД");
} ловить д) {
консоль.ошибка (е);
консоль.log("Не удалось завершить операции с базой данных");
Ждите сеанс.abortTransaction();
} окончательно {
Ждите сеанс.конец сеанса();
консоль.log("Завершенный сеанс транзакции");
}
};

А создавать запрос, который выполняется в транзакции, обычно принимает и возвращает массив. Вы можете увидеть это в приведенном выше коде, где он создает новая работа и хранит свои _идентификатор имущество вновыйJobId переменная.

Вот демонстрация того, как работают вышеуказанные функции:

константа mockUser = {
имя: "Тимми Омолана",
электронная почта: "[email protected]",
};

константа мокджоб = {
должность: "Менеджер по продажам",
место: "Лагос, Нигерия",
зарплата: "$40,000",
электронная почта пользователя: "[email protected]", // электронная почта созданного пользователя
};

константа стартовый сервер = асинхронный () => {
Ждите подключить БД();
Ждите создать пользователя (мок-пользователя);
Ждите создать задание (макет задания);
};

стартсервер()
.затем()
.поймать((ошибка) => консоль.log (ошибка));

Если вы сохраните этот код и запустите его, используя запуск нпм или узел команда, она должна выдать такой вывод:

Другой способ реализации транзакций ACID в MongoDB с использованием Mongoose — использование с транзакцией() функция. Этот подход обеспечивает небольшую гибкость, поскольку все запросы выполняются внутри функции обратного вызова, которую вы передаете функции в качестве аргумента.

Вы можете реорганизовать приведенную выше транзакцию базы данных для использования с транзакцией() так:

константа создать задание = асинхронный (работа) => {
константа {userEmail, должность, местоположение, зарплата} = работа;

// получаем пользователя из БД
константа пользователь = Ждите userCollection.findOne({ электронная почта: электронная почта пользователя });

// начинаем транзакционную сессию
константа сеанс = Ждите соединение.startSession();

// запускаем все запросы к базе данных в блоке try-catch
пытаться {
константа транзакцияУспех = Ждите сеанс.с транзакцией(асинхронный () => {
константа новая работа = Ждите jobCollection.create(
[
{
заголовок,
расположение,
зарплата,
постер: user._id,
},
],
{ сеанс }
);

консоль.log("Создано новый работа выполнена успешно!");
консоль.log (новая работа[0]);

// добавить вакансию в список опубликованных вакансий пользователей
константа идентификатор новой работы = новая работа[0]._идентификатор;
константа добавленопользователю = Ждите userCollection.findByIdAndUpdate(
ID пользователя,
{ $adToSet: { рабочие места: идентификатор новой работы } },
{ сеанс }
);

консоль.log("Вакансия успешно добавлена ​​в список вакансий пользователя");
консоль.log (добавленопользователю);
});

если (успешная транзакция) {
консоль.log("Успешно проведена транзакция БД");
} еще {
консоль.log("Транзакция не удалась");
}
} ловить д) {
консоль.ошибка (е);
консоль.log("Не удалось завершить операции с базой данных");
} окончательно {
Ждите сеанс.конец сеанса();
консоль.log("Завершенный сеанс транзакции");
}
};

Это даст тот же результат, что и предыдущая реализация. Вы можете свободно выбирать, какой стиль использовать при реализации транзакций базы данных в MongoDB.

Эта реализация не использует совершитьтранзакцию() и прервать транзакцию () функции. Это потому, что с транзакцией() Функция автоматически фиксирует успешные транзакции и прерывает неудачные. Единственная функция, которую вы должны вызывать во всех случаях, это сессия.endSession() функция.

Реализация транзакций базы данных ACID в MongoDB

Транзакции базы данных просты в использовании, если они выполняются правильно. Теперь вы должны понимать, как транзакции базы данных работают в MongoDB и как вы можете реализовать их в приложениях Node.js.

Для дальнейшего изучения идеи транзакций ACID и того, как они работают в MongoDB, рассмотрите возможность создания финтех-кошелька или приложения для ведения блога.