Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Транзакция в базах данных
Транзакция — это последовательность одной или нескольких операций (SQL запросов), которые выполняются как единая атомарная единица. Либо все операции в транзакции выполняются успешно, либо все откатываются без каких-либо изменений в БД.
ACID свойства
Транзакция должна обладать четырьмя критическими свойствами (ACID):
1. Atomicity (Атомарность)
- Транзакция выполняется либо полностью, либо не выполняется вообще
- Нет состояния "полувыполненной" транзакции
2. Consistency (Согласованность)
- База данных переходит из одного непротиворечивого состояния в другое
- Все ограничения целостности сохраняются
3. Isolation (Изолированность)
- Одновременные транзакции не влияют друг на друга
- Данные одной транзакции невидимы для других до коммита
4. Durability (Стойкость)
- После успешного коммита данные сохраняются
- Сохранение гарантируется даже при отказе системы
Пример на Go с PostgreSQL
package main
import (
"database/sql"
"log"
"_ "github.com/lib/pq"
)
func transferMoney(db *sql.DB, fromAccount, toAccount string, amount int) error {
// Начинаем транзакцию
tx, err := db.Begin()
if err != nil {
return err
}
// Снимаем со счёта fromAccount
_, err = tx.Exec(
"UPDATE accounts SET balance = balance - $1 WHERE id = $2",
amount, fromAccount,
)
if err != nil {
tx.Rollback() // Откат при ошибке
return err
}
// Добавляем на счёт toAccount
_, err = tx.Exec(
"UPDATE accounts SET balance = balance + $1 WHERE id = $2",
amount, toAccount,
)
if err != nil {
tx.Rollback() // Откат при ошибке
return err
}
// Коммитим транзакцию
return tx.Commit().Error
}
Уровни изоляции
Разные СУБД предоставляют разные уровни изоляции:
1. Read Uncommitted — самый низкий, допускает грязное чтение
2. Read Committed — читаем только коммиченные данные (PostgreSQL по умолчанию)
3. Repeatable Read — в пределах одной транзакции видим консистентный снимок
4. Serializable — полная изоляция, как будто транзакции выполняются последовательно
Контролирование уровня изоляции в Go
var isolationLevel sql.IsolationLevel
isolationLevel = sql.LevelSerializable
tx, err := db.BeginTx(ctx, &sql.TxOptions{
Isolation: isolationLevel,
ReadOnly: false,
})
Практические аспекты
- Deadlock: При одновременных транзакциях возможны блокировки, нужна повторная попытка
- Длинные транзакции: Держат блокировки, снижают производительность
- Коммиты: Выполняй как можно быстрее после завершения всех операций
- Откаты: Используй Rollback при любой ошибке в процессе транзакции
Транзакции критически важны для обеспечения целостности данных и надёжности приложений, работающих с базами данных.