Что такое транзакция в базах данных и как она реализуется в Node.js?

«Что такое транзакция в базах данных и как она реализуется в Node.js?» — вопрос из категории Базы данных, который задают на 35% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Транзакция — это атомарная последовательность операций с базой данных, которая либо выполняется полностью (commit), либо полностью откатывается (rollback) при ошибке. В Node.js работа с транзакциями зависит от используемой базы данных и драйвера/ORM.

Реализация транзакций с PostgreSQL через node-postgres:

const { Client } = require('pg');
const client = new Client();
await client.connect();

// Начало транзакции
await client.query('BEGIN');

try {
  // Операция 1: Создание пользователя
  await client.query(
    'INSERT INTO users(name, email) VALUES($1, $2) RETURNING id',
    ['John Doe', 'john@example.com']
  );

  // Операция 2: Создание заказа для пользователя
  const result = await client.query(
    'INSERT INTO orders(user_id, amount) VALUES($1, $2) RETURNING id',
    [1, 100.50]
  );

  // Фиксация транзакции
  await client.query('COMMIT');
  console.log('Transaction committed, order ID:', result.rows[0].id);
} catch (error) {
  // Откат при любой ошибке
  await client.query('ROLLBACK');
  console.error('Transaction rolled back:', error.message);
  throw error;
} finally {
  await client.end();
}

Реализация через Sequelize ORM:

const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');

const transaction = await sequelize.transaction({
  isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED
});

try {
  // Создание пользователя в транзакции
  const user = await User.create({
    name: 'Alice',
    email: 'alice@example.com'
  }, { transaction });

  // Создание связанной записи
  await Order.create({
    userId: user.id,
    total: 250.75,
    status: 'pending'
  }, { transaction });

  // Фиксация
  await transaction.commit();
} catch (error) {
  // Автоматический откат
  await transaction.rollback();
  console.error('Transaction failed:', error);
}

Свойства ACID в контексте Node.js:

  1. Атомарность (Atomicity):

    // Либо обе операции выполнятся, либо ни одной
    await transferFunds(senderId, receiverId, amount);
  2. Согласованность (Consistency):

    // Транзакция гарантирует соблюдение constraints
    // FOREIGN KEY, CHECK, NOT NULL и т.д.
  3. Изолированность (Isolation):

    // Уровни изоляции в PostgreSQL через Node.js
    const levels = {
     READ_UNCOMMITTED: 'READ UNCOMMITTED',
     READ_COMMITTED: 'READ COMMITTED',    // По умолчанию
     REPEATABLE_READ: 'REPEATABLE READ',
     SERIALIZABLE: 'SERIALIZABLE'
    };
  4. Долговечность (Durability):

    // После COMMIT данные гарантированно сохраняются
    // даже при сбое системы (WAL - Write Ahead Logging)

Практические сценарии использования в Node.js:

  • Финансовые операции (переводы между счетами)
  • Создание заказов с несколькими позициями
  • Обновление инвентаря при покупке
  • Миграции данных с сохранением целостности

Видео-ответы