偵測database/sql中的交易提交或回滾
在database/sql包及其驅動介面和Tx類型中,它不是明確可以確定事務是否已提交或回滾,而無需嘗試另一個事務。然後可以檢查後續嘗試傳回的錯誤以推斷交易的狀態。
為了避免額外的開銷,可以考慮在提交或回滾後將 Tx 變數設為 nil。但是,通常不鼓勵這種方法,因為它可能會導致意外行為和記憶體洩漏。
建議的解決方案是使用事務處理程序來包裝事務邏輯。這可確保 Begin()、Commit() 和 Rollback() 呼叫始終在同一函數內,從而簡化追蹤並確保使用 defer 語句進行正確的事務處理。
例如:
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() // err is non-nil; don't change it } else { err = tx.Commit() // err is nil; if Commit returns error update err } }() err = txFunc(tx) return err }
使用此處理程序,事務邏輯可以封裝如下:
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 } return nil }) }
這種方法使事務代碼簡潔並確保處理的一致性。請注意,事務處理程序使用recover() 來攔截恐慌並立即啟動回滾。但是,應該強調的是,返回錯誤優於恐慌。
以上是如何在 Go 的 `database/sql` 套件中可靠地檢測資料庫事務提交或回滾?的詳細內容。更多資訊請關注PHP中文網其他相關文章!