Ответ
ACID — это набор из четырех ключевых свойств, гарантирующих надежность и предсказуемость транзакций в системах управления базами данных (СУБД).
Расшифровка принципа ACID:
| Свойство | Описание | Пример нарушения |
|---|---|---|
| Atomicity (Атомарность) |
Транзакция выполняется как единое целое. Либо выполняются все ее операции, либо ни одна. Недопустимо частичное выполнение. | При переводе денег списались средства с одного счета, но не зачислились на другой. |
| Consistency (Согласованность) |
Транзакция переводит базу данных из одного валидного состояния в другое, соблюдая все бизнес-правила, ограничения целостности (constraints), триггеры. | После транзакции нарушилось ограничение уникальности или внешний ключ. |
| Isolation (Изолированность) |
Параллельно выполняемые транзакции не должны влиять друг на друга. Результаты их работы должны быть такими, как если бы они выполнялись последовательно. Уровни изоляции (Read Uncommitted, Read Committed и др.) определяют степень этой изоляции. | Феномен "грязного" чтения (Dirty Read), когда одна транзакция видит незафиксированные изменения другой. |
| Durability (Долговечность) |
После успешного завершения транзакции (commit) внесенные ею изменения становятся постоянными и сохраняются даже в случае сбоя системы (отключение питания, авария). | После подтверждения перевода данные о нем были потеряны из-за сбоя диска. |
Практический пример на SQL/JDBC:
Connection conn = dataSource.getConnection();
try {
conn.setAutoCommit(false); // Начало транзакции (отключение auto-commit)
PreparedStatement stmt1 = conn.prepareStatement(
"UPDATE accounts SET balance = balance - ? WHERE id = ?");
stmt1.setBigDecimal(1, amount);
stmt1.setInt(2, fromAccountId);
stmt1.executeUpdate();
PreparedStatement stmt2 = conn.prepareStatement(
"UPDATE accounts SET balance = balance + ? WHERE id = ?");
stmt2.setBigDecimal(1, amount);
stmt2.setInt(2, toAccountId);
stmt2.executeUpdate();
conn.commit(); // ФИКСАЦИЯ. Только здесь изменения становятся видимыми и постоянными.
System.out.println("Транзакция успешно завершена.");
} catch (SQLException e) {
conn.rollback(); // ОТКАТ (ROLLBACK) при любой ошибке. Все изменения отменяются (Atomicity).
System.out.println("Транзакция откачена: " + e.getMessage());
} finally {
conn.setAutoCommit(true); // Возвращаем режим по умолчанию
conn.close();
}