O total de dinheiro (R$ 150) é uma invariante: transferir muda quem tem, nunca o total. Sem transação, uma falha entre o débito e o crédito quebra essa invariante e o dinheiro evapora. A transação garante que as duas operações são uma coisa só: ou as duas valem, ou nenhuma.
| A · Atomicidade | Tudo ou nada. Falhou no meio, desfaz tudo (rollback). |
| C · Consistência | Vai de um estado válido a outro, respeitando as invariantes (total, constraints). |
| I · Isolamento | Transações concorrentes não enxergam o meio uma da outra. |
| D · Durabilidade | Depois do commit, sobrevive a um crash (graças ao log, aula 23). |
Transação em Go (database/sql)
func transferir(db *sql.DB, de, para string, valor int) error {
tx, err := db.Begin()
if err != nil { return err }
defer tx.Rollback() // no-op se já houve Commit
_, err = tx.Exec("UPDATE contas SET saldo = saldo - $1 WHERE id = $2", valor, de)
if err != nil { return err } // o defer reverte o débito
_, err = tx.Exec("UPDATE contas SET saldo = saldo + $1 WHERE id = $2", valor, para)
if err != nil { return err }
return tx.Commit() // só aqui o dinheiro "existe" de verdade
}