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

Ответ

Транзакция — это последовательность операций с базой данных, которая выполняется как единая, неделимая (атомарная) единица работы. Она гарантирует, что все операции либо будут успешно выполнены и зафиксированы (COMMIT), либо, в случае сбоя, полностью отменены (ROLLBACK), возвращая систему в исходное состояние.

Это обеспечивает целостность данных. Классический пример — банковский перевод: списание средств с одного счета и зачисление на другой должны произойти вместе или не произойти вовсе.

Основные свойства транзакций описываются акронимом ACID:

  • Atomicity (Атомарность): Гарантирует, что транзакция выполняется по принципу "всё или ничего".
  • Consistency (Согласованность): Транзакция переводит базу данных из одного согласованного состояния в другое. Все правила и ограничения (constraints) должны быть соблюдены.
  • Isolation (Изолированность): Параллельно выполняющиеся транзакции не должны влиять друг на друга. Результат их одновременного выполнения должен быть таким же, как если бы они выполнялись последовательно.
  • Durability (Долговечность): Если транзакция успешно завершена, ее результаты должны быть сохранены и не могут быть потеряны даже в случае сбоя системы (например, отключения питания).

Упрощенный пример на Python с sqlite3:

import sqlite3

# Используем 'with' для автоматического закрытия соединения
with sqlite3.connect('bank.db') as conn:
    cursor = conn.cursor()
    sender_id = 1
    receiver_id = 2
    amount = 100

    try:
        # Списание средств со счета отправителя
        cursor.execute("UPDATE accounts SET balance = balance - ? WHERE id = ?", (amount, sender_id))
        # Зачисление средств на счет получателя
        cursor.execute("UPDATE accounts SET balance = balance + ? WHERE id = ?", (amount, receiver_id))

        # Если обе операции успешны, фиксируем транзакцию
        conn.commit()
        print("Перевод успешно выполнен.")

    except sqlite3.Error as e:
        # При любой ошибке откатываем все изменения
        conn.rollback()
        print(f"Ошибка! Транзакция отменена: {e}")