Ответ
Грязное чтение (Dirty Read) — это проблема, возникающая в многопоточных системах при работе с базами данных. Она происходит, когда одна транзакция (Т1) читает данные, которые были изменены другой транзакцией (Т2), но ещё не были зафиксированы (не прошел COMMIT
).
Основной риск: если транзакция Т2 в итоге будет отменена (ROLLBACK
), то транзакция Т1 будет работать с неактуальными, "грязными" данными, которые по факту никогда не существовали в базе данных. Это может привести к серьезным ошибкам в логике приложения.
Аналогия: Представьте, что вы читаете черновик документа, над которым работает ваш коллега. Вы делаете выводы на основе этого черновика, но затем коллега решает удалить все свои правки. В итоге ваша работа основана на неверной информации.
В Go это можно проиллюстрировать на примере работы с БД:
// Предполагается, что уровень изоляции установлен в READ UNCOMMITTED
tx1, _ := db.Begin()
tx2, _ := db.Begin()
// Транзакция 1 обновляет баланс, но пока не фиксирует изменения
tx1.Exec("UPDATE accounts SET balance = 100 WHERE id = 1")
// Транзакция 2 читает НЕзафиксированные (грязные) данные
var balance int
tx2.QueryRow("SELECT balance FROM accounts WHERE id = 1").Scan(&balance)
fmt.Println(balance) // Выведет 100
// Транзакция 1 откатывает изменения
tx1.Rollback()
// Теперь в базе данных баланс остался прежним, но транзакция tx2 уже
// успела прочитать неверное значение 100 и может использовать его в дальнейших операциях.
Такое поведение возможно только при самом низком уровне изоляции транзакций — READ UNCOMMITTED
. Чтобы избежать грязного чтения, используют более строгие уровни, такие как READ COMMITTED
(по умолчанию во многих СУБД, например, в PostgreSQL), REPEATABLE READ
или SERIALIZABLE
.