Transaction
- Go kursu
- İleri seviye
- Ders 29/68
- 4 dk
Begin, Commit ve Rollback ile transaction öğrenirsin.
Transaction
Birden çok işlemin ya hep birlikte olmasını ya da hiç olmamasını istiyorsan transaction kullanırsın. db.Begin() bir *sql.Tx verir; işlemler tx üzerinden yapılır, sonunda Commit ya da Rollback çağrılır.
tx, err := db.Begin()
if err != nil { return err }
defer tx.Rollback() // Commit sonrası etkisizdir
if _, err := tx.Exec("UPDATE hesap SET bakiye = bakiye - 100 WHERE id = 1"); err != nil { return err }
if _, err := tx.Exec("UPDATE hesap SET bakiye = bakiye + 100 WHERE id = 2"); err != nil { return err }
return tx.Commit()defer tx.Rollback deseni
defer tx.Rollback() erken dönüşlerde ve hatalarda transaction'ı geri alır. Commit başarılı olduktan sonra Rollback çağrısı sql.ErrTxDone döner ve hiçbir şey yapmaz; bu yüzden desen güvenlidir. Bağlamla çalışmak için db.BeginTx(ctx, nil) kullanılır; bağlam iptal edilirse transaction otomatik geri alınır.
Uygulama Transaction akışı
Gerçek veritabanı olmadan akışı modelle: transfer(fail bool) string fonksiyonu yaz. fail true ise "rollback", değilse "commit" döndürsün. transfer(false) ve transfer(true) sonuçlarını tek satırda yazdır.
Başlangıç kodu
package main
import "fmt"
func main() {
// buraya yaz
}Örnek çözüm
package main
import "fmt"
func transfer(fail bool) string {
if fail {
return "rollback"
}
return "commit"
}
func main() {
fmt.Println(transfer(false), transfer(true))
}Beklenen çıktı
commit rollback
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Transaction içinde sorguyu neden <code>db.Exec</code> yerine <code>tx.Exec</code> ile çalıştırırsın?
- Fark yoktur
- db.Exec havuzdan başka bir bağlantı alır ve transaction dışında kalır Doğru cevap
- tx.Exec daha hızlıdır
- db.Exec transaction'ı kapatır
Açıklama: Transaction tek bir bağlantıya bağlıdır; db üzerinden yapılan işlemler o bağlantıyı kullanmaz ve geri alınmaz.
2 Onayla
if err := step(tx); err != nil {
return err
}
return tx.____()
if err := step(tx); err != nil {
return err
}
return tx.Commit()
Açıklama: Commit değişiklikleri kalıcı yapar; öncesinde hata çıkarsa defer'deki Rollback devreye girer.
3 Transaction adımları
| Kavram | Anlamı |
|---|---|
db.Begin |
Başlatır |
tx.Exec |
İçinde çalışır |
tx.Commit |
Kalıcı yapar |
tx.Rollback |
Geri alır |