データベース/SQL でのトランザクションのコミットまたはロールバックの検出
ドライバー インターフェイスと Tx タイプを備えたデータベース/SQL パッケージでは、トランザクションのコミットまたはロールバックは検出されません。別のトランザクションを試行せずに、トランザクションがコミットされたかロールバックされたかを判断することが明示的に可能です。その後、後続の試行で返されたエラーを調べて、トランザクションのステータスを推測できます。
追加のオーバーヘッドを回避するには、コミットまたはロールバック後に 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 中国語 Web サイトの他の関連記事を参照してください。