Назад к вопросам
Middle
118
questionbank

Что такое атомарность и консистентность?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Атомарность (Atomicity) и консистентность (Consistency) — это два из четырех свойств ACID транзакций в базах данных, обеспечивающие надежность операций.

Атомарность Гарантирует, что транзакция либо выполняется полностью, либо не выполняется вовсе. Если любая часть транзакции завершается с ошибкой, вся транзакция откатывается до исходного состояния. Нет частично выполненных транзакций.

// Пример атомарности в SQL (не Java-код, но для иллюстрации концепции)
// Предположим, перевод 100 единиц с одного счета на другой
public void transfer(int fromAccountId, int toAccountId, double amount) {
    Connection connection = null;
    try {
        connection = dataSource.getConnection();
        connection.setAutoCommit(false); // Отключаем автокоммит для контроля транзакции

        // Списываем средства с одного счета
        String debitSql = "UPDATE accounts SET balance = balance - ? WHERE id = ?";
        try (PreparedStatement debitStmt = connection.prepareStatement(debitSql)) {
            debitStmt.setDouble(1, amount);
            debitStmt.setInt(2, fromAccountId);
            int updatedRows = debitStmt.executeUpdate();
            if (updatedRows == 0) {
                throw new SQLException("Account not found or insufficient funds: " + fromAccountId);
            }
        }

        // Зачисляем средства на другой счет
        String creditSql = "UPDATE accounts SET balance = balance + ? WHERE id = ?";
        try (PreparedStatement creditStmt = connection.prepareStatement(creditSql)) {
            creditStmt.setDouble(1, amount);
            creditStmt.setInt(2, toAccountId);
            int updatedRows = creditStmt.executeUpdate();
             if (updatedRows == 0) {
                throw new SQLException("Account not found: " + toAccountId);
            }
        }

        connection.commit(); // Все операции успешны, фиксируем транзакцию
    } catch (SQLException e) {
        if (connection != null) {
            try {
                connection.rollback(); // При ошибке откатываем транзакцию
            } catch (SQLException rollbackEx) {
                // Логирование ошибки отката
            }
        }
        // Обработка ошибки транзакции
    } finally {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException closeEx) {
                // Логирование ошибки закрытия
            }
        }
    }
}

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

Консистентность достигается благодаря сочетанию свойств базы данных (ограничения, триггеры) и логики приложения.

// Пример консистентности (через логику приложения и ограничения БД)
// В приведенном выше коде transfer():
// 1. Проверка достаточного баланса (часть соблюдения консистентности) косвенно обеспечивается
//    через проверку количества обновленных строк или с использованием CHECK ограничения в БД.
// 2. Если debitStmt.executeUpdate() вернул 0, это может означать недостаточный баланс (если есть CHECK ограничение)
//    или отсутствие счета, что нарушает консистентность, если бы мы продолжили.
// 3. Откат транзакции при любой ошибке гарантирует, что база данных не останется в промежуточном,
//    неконсистентном состоянии (например, списали, но не зачислили).

// Пример CHECK ограничения в SQL для поддержания консистентности баланса:
// ALTER TABLE accounts ADD CONSTRAINT check_positive_balance CHECK (balance >= 0);