Implement pessimistic locking in Go by wrapping database transactions with sql.Tx and using sql.TxOptions{Isolation: sql.LevelSerializable} to ensure exclusive access. This approach blocks other transactions from reading or writing the same data until the current transaction commits or rolls back.
import (
"database/sql"
_ "github.com/lib/pq"
)
func updateBalance(db *sql.DB, accountID int, amount int64) error {
tx, err := db.BeginTx(nil, &sql.TxOptions{
Isolation: sql.LevelSerializable,
ReadOnly: false,
})
if err != nil {
return err
}
defer tx.Rollback()
var currentBalance int64
if err := tx.QueryRow("SELECT balance FROM accounts WHERE id = $1 FOR UPDATE", accountID).Scan(¤tBalance); err != nil {
return err
}
if _, err := tx.Exec("UPDATE accounts SET balance = $1 WHERE id = $2", currentBalance+amount, accountID); err != nil {
return err
}
return tx.Commit()
}