Veritabanı/sql ve sürücü paketlerini ve Tx'i kullanarak, bir işlemin başka bir işlem yapmadan mı, yoksa geri alınıp alınmayacağını ve bir hata olarak algılandığını algılamayabilir. Sonuç ve daha sonra hatanın türünü belirlemek için hatayı incelemek. Tx nesnesinden kararlı olup olmadığına karar vermek istiyorum. Elbette, Tx kullanan fonksiyonda bir başka değişken tanımlayabilir ve ayarlayabilirim, fakat bende bunların bir numarası var ve her seferinde 2 kere (değişken ve atama). Ayrıca gerekirse Geri Alma işlemini yapmak için ertelenmiş bir işlevim var ve boole değişkenini geçirmesi gerekiyor.
Tx değişkeninin bir Kombinasyon veya Geri Alma işleminden sonra sıfırlanması ve GC'nin herhangi bir belleği kurtarması mı, yoksa hayır yok mu yoksa daha iyi bir alternatif mi olduğu kabul edilebilir mi?database/sql Tx - Tespit veya Geri Alma Algılama
cevap
Bunu neden yapmak zorunda kaldınız? Begin()
numaralı çağrı, Commit()
veya Rollback()
numaralı telefonu çağırmalı ve uygun bir hata döndürmelidir. Ben kaydetme veya geri gerekip gerekmediğini görmek için error
kontrol ediyorum nasıl
func (s Service) DoSomething() (err error) {
tx, err := s.db.Begin()
if err != nil {
return
}
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
if _, err = tx.Exec(...); err != nil {
return
}
if _, err = tx.Exec(...); err != nil {
return
}
// ...
return
}
Bildirimi:
Örneğin, bu kod, bir kaydetme veya geri bir hata döndürdü olup olmamasına bağlı olarak yapar. Yukarıdaki örnek, ancak panik işlemez.
Her veritabanı rutininde commit/rollback mantığı yapmayı sevmiyorum, bu yüzden bunları genellikle bir işlem işleyicisine sardım. Bunun şey satırları: Bu bana yerine bunu sağlar
func Transact(db *sql.DB, txFunc func(*sql.Tx) error) (err error) {
tx, err := db.Begin()
if err != nil {
return
}
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p) // re-throw panic after Rollback
} else if err != nil {
tx.Rollback()
} else {
err = tx.Commit()
}
}()
err = txFunc(tx)
return err
}
: my işlem içinde birşey panikler eğer otomatik işlem işleyici tarafından işlenir oldu o
func (s Service) DoSomething() error {
return Transact(s.db, func (tx *sql.Tx) error {
if _, err := tx.Exec(...); err != nil {
return err
}
if _, err := tx.Exec(...); err != nil {
return err
}
})
}
dikkat edin.
Gerçek uygulamamda, istenmeyen aramaları Commit()
veya Rollback()
önlemek için * sql.Tx yerine bir arabirim iletiyorum.
İşte göstermek için basit bir parçacık İşte nasıl defer
eserleri (baskılar 4 değil, 5):
package main
func test() (i int) {
defer func() {
i = 4
}()
return 5
}
func main() {
println(test())
}
güzel cevap! Sanırım ikinci doSomething() uygulamanızın sonuna doğru bir "dönüş sıfır" kaçırdınız. – splinter123
Luke, err nasıl ve ne zaman değerlendirilir? Dokümantasyona göre "err", erteleme çağrısında ilk ilan edildiğinde değeri almalıdır.Yani bu aslında benim için biraz kafa karıştırıcı, çünkü ertelemede kullanılan "err" değeri değişiyor gibi görünüyor. – mirage
err, ertelemeden önce: = (kolon eşit) ile bildirilir. Anon func onu yakalar. Erteleme değeri döndürülmeden hemen önce çağrılır. Bu ayarlanmasına izin veriyor. Bir panik meydana geldiğinde, kurtarılır, bir hataya dönüştürülür, daha sonra iade edilir. Bir hata herhangi bir şekilde olursa, geri dönüş gerçekleşir. Sonunda, bir hata yoksa ve hata (hata) durumunda err (şu anda sıfır) Komutlar döndürme değeri olarak ayarlanmışsa bir taahhüt gerçekleşir. – Luke
- 1. Android sqlite geri alma
- 2. aşağı kaydırma Algılama veya jQuery
- 3. Geri çağırma işlevlerinden gelen değişkenleri geri alma
- 4. SQL Geri alma sorusu
- 5. PDO'dan Nesneleri Geri Alma
- 6. DbContextTransaction Geri Alma
- 7. Git: Birleştirme "geri alma"
- 8. Ölçü-Komutu veya StopWatch Karışık/Yanlış Sonuçları Geri Alma
- 9. Tespit Etme Geri Dönüşüm öğeleri öğelerin dışında
- 10. Çalışan işlemlerin adlarını geri alma
- 11. Javascript regex ile satır sonu veya sonu sonu Algılama
- 12. Meteor aygıt algılama android veya ios?
- 13. bir geri alma garantisi ile
- 14. Toplu kopyalama için geri alma
- 15. İşlem ağ kullanımını geri alma
- 16. ORACLE Geri Alma ve Tetik
- 17. Ssis'te geri alma nasıl yapılır?
- 18. Python geri alma yöntemi alay
- 19. Bir Git rollback'i geri alma
- 20. EJB: kaçının İşlem geri alma
- 21. Java'da Geri Alma İşlemi Prosedürü
- 22. TortoiseSVN'de bir işlemi geri alma
- 23. İçeriği bir parçadan geri alma
- 24. Backendess'i Kullanan Kullanıcıları Geri Alma
- 25. php hatalarında erken hataları algılama
- 26. PHP'de programlama dili algılama
- 27. Spring "" tx: ek açıklama temelli "öğesi için" tx "öneki bağlı değil."
- 28. Windows'da tam ekran modunu algılama
- 29. Rayları Geri Alma Model Sütun İsimleri
- 30. Brent'in çevrim algılama algoritması
Sorunu anlamak eğer emin değilim. Bir işlemi Commit veya Rollback ile bitirmelisiniz, böylece ne yaptığınızı biliyorsunuz ama bunu fazladan bir değişkende hatırlamak istemiyorsunuz? Tx ve bool'u kendi RememberingTx'inize sarabilirsiniz, bu durum satır sayısını biraz azaltacaktır. GC sorusu ile ilgili olarak: Nil olsun ya da olmasın farketmez: Bir referans bırakılmadığında bellek geri alınacaktır. Yani: Evet, var tx * Tx'e sahip olabilirsiniz; makasla kesme; eğer koşul varsa {tx.Commit; tx = nil} else {tx.Rollback}; makasla kesme; tx == nil {commited oldu} başka {rollbacked} oldu ama çirkin hissediyor. – Volker
Bu tür bir şeydir, ancak Tx sıfır değilse geri alma yapan ertelenmiş bir fon var. Bir işlem gerçekleştirildikten sonra, Tx yine de kullanılamaz, bu yüzden onu nil olarak ayarlamayı planlıyorum. Güzel değil, ancak geri alma girişiminde bulunmak ve hata mesajını test etmek de hoş değil. Sorun şu ki AFAIK, işlemin Tx'den "tamamlandı" olup olmadığını test etmenin bir yolu yok. Bu şekilde neden yapıldığından emin değilim, belki de performans. –