Ответ
Транзакция — это последовательность операций с базой данных, которая рассматривается как единая логическая единица работы. Главная цель транзакций — обеспечить целостность и согласованность данных, даже при одновременном доступе или сбоях.
Транзакции гарантируют соблюдение принципов ACID:
- Atomicity (Атомарность): Либо все операции внутри транзакции успешно выполняются, либо ни одна из них не применяется. Не бывает частичного выполнения.
- Consistency (Согласованность): Транзакция переводит базу данных из одного корректного состояния в другое. Все правила и ограничения (constraints) базы данных соблюдаются.
- Isolation (Изолированность): Параллельно выполняющиеся транзакции не должны влиять друг на друга. Результат их одновременного выполнения должен быть таким же, как если бы они выполнялись последовательно.
- Durability (Долговечность): Если транзакция успешно завершена (
COMMIT), её результаты сохраняются навсегда и не будут потеряны даже в случае сбоя системы (например, отключения питания).
Пример перевода денег в Go:
// db - это ваше соединение с БД (*sql.DB)
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
// Снимаем деньги с одного счета
_, err = tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
if err != nil {
// Если ошибка, откатываем все изменения
tx.Rollback()
return
}
// Зачисляем на другой счет
_, err = tx.Exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
if err != nil {
// Если здесь ошибка, первая операция тоже будет отменена
tx.Rollback()
return
}
// Если все прошло успешно, применяем изменения
err = tx.Commit()
if err != nil {
log.Fatal(err)
} Ответ 18+ 🔞
Давай разберём эту тему про транзакции, а то я вижу, у некоторых в голове про них такая же каша, как в моём холодильнике после пятницы.
Представь себе, блядь, что ты переводишь сто рублей другу. Ты снял их со своего счёта — и тут бац, свет вырубили. Если бы не транзакции, деньги бы просто испарились, а друг остался бы с носом, и ты — мудак. Вот чтобы такого пиздеца не было, и придумали транзакции.
Это, сука, такая неделимая пачка операций: либо всё проходит на ура, либо нихуя не происходит. Это и есть атомарность, ёпта. Как в кино: «Либо грудь в крестах, либо голова в кустах». Никаких промежуточных состояний, когда деньги уже списали, но ещё не зачислили — это же пиздопроебибна какая-то.
Дальше — согласованность. Это значит, что после всей этой движухи твоя база данных не превратится в бред сумасшедшего. Все правила, все ограничения — они на месте. Не может на счету уйти в минус, если ты это не разрешил. Всё чётко, как у швейцара в дорогом отеле.
Изолированность — это вообще отдельная песня, блядь. Представь, что ты и твой кореш одновременно лезете в один и тот же счёт. Без изоляции вы можете нахуячить там такого, что потом и черт ногу сломит. А с ней — каждая транзакция живёт в своём мирке, будто в параллельной вселенной, и не видит промежуточного говна других транзакций. Красота!
Ну и долговечность, мать её. Это когда ты нажал «Подтвердить», и система тебе говорит: «Всё, чувак, я это запомнила навечно. Даже если сервер сейчас взорвётся, я восстановлюсь и доведу дело до конца». Не то что некоторые люди, которые обещают и забывают, пидарасы шерстяные.
Вот, смотри, как это выглядит в коде на Go, если переводить бабки:
// db - это ваше соединение с БД (*sql.DB)
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
// Снимаем деньги с одного счета
_, err = tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
if err != nil {
// Если ошибка, откатываем все изменения
tx.Rollback()
return
}
// Зачисляем на другой счет
_, err = tx.Exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
if err != nil {
// Если здесь ошибка, первая операция тоже будет отменена
tx.Rollback()
return
}
// Если все прошло успешно, применяем изменения
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
Видишь? Начинаем транзакцию. Пытаемся снять сотку. Не получилось — Rollback(), и всё, как будто и не пытались. Сняли? Отлично. Пытаемся зачислить. Тут облом — снова Rollback(), и первое списание тоже откатывается, ёбана! Всё прошло гладко? Commit(), и все изменения прибиваются гвоздями к истории. Никаких полумер, блядь. Либо пан, либо пропал. Вот так вот, в рот меня чих-пых, и работают эти ваши транзакции.