データベース/ SQLとドライバパッケージとTxを使用すると、トランザクションがコミットまたはロールバックされていないかどうかを検出することはできません。エラーの種類を判断するためにエラーを調べます。私はTxオブジェクトからコミットされているかどうかを判断できるようにしたいと思います。確かに、Txを使用する関数で別の変数を定義して設定することはできますが、かなりの数があり、毎回2回(変数と代入)です。私はまた、必要に応じてロールバックを行う遅延関数を持っており、bool変数を渡す必要があります。
コミットまたはロールバック後にTx変数をnilに設定しても問題はありません.GCはメモリを回復しますか、それともno-noですか、それとも良い方法がありますか?データベース/ SQL Tx検出コミットまたはロールバック
答えて
なぜこれを行う必要がありますか? Begin()
を呼び出す関数は、Commit()
またはRollback()
も呼び出して、適切なエラーを返す必要があります。例えば
、このコードは、エラーが返されるかどうかに応じてコミットまたはロールバックん:私は、私がコミットまたはロールバックするかどうかを確認するためにerror
をチェックしていますか
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
}
注意してください。ただし、上記の例ではパニックを処理しません。
私はすべてのデータベースルーチンでコミット/ロールバックロジックを行うのが好きではありません。そのため、通常はトランザクションハンドラでラップします。この線に沿って何か:これは私が代わりにこれを行うことができます
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
}
:私のトランザクション内の何かがパニックあれば、それが自動的にトランザクションハンドラによって処理されますことを
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
}
})
}
注意してください。
私の実際の実装では、Commit()
またはRollback()
への不要な呼び出しを防ぐために、* sql.Txの代わりにインターフェイスを渡します。
はここで実証するための簡単なスニペットですかdefer
作品(版画4、ない5):
package main
func test() (i int) {
defer func() {
i = 4
}()
return 5
}
func main() {
println(test())
}
すてきな答え!私はあなたの2番目のdoSomething()実装の最後に向かって "return nil"を見逃したと思います。 – splinter123
ルーク、いつ、どのようにエラーが評価されるのですか?ドキュメントごとに、 "err"はdefer呼び出しで最初に宣言されたときにその値を取得する必要があります。だから、これは実際には私のために少し混乱しています。なぜなら、 "エラー"の値は、遅延で使われているように変わるようです。 – mirage
遅延はvia:=(コロン等価)の前に宣言されます。 anon funcがそれをキャプチャします。 Deferは、値が返される直前に呼び出されます。それはそれを設定することができます。パニックが発生すると、パニックが回復し、エラーに変わり、その後返されます。何らかのエラーが発生した場合、ロールバックが発生します。最後に、エラーがない場合にはコミットが発生し、エラーの場合はエラー(現在はnil)が戻り値を確定します。 – Luke
- 1. SQLトランザクションのロールバックとコミット
- 2. SQL Serverでトランザクションをロールバックまたはコミットする方法
- 3. バッチの最後にコミット不能なトランザクションが検出されました。トランザクションはロールバックされます
- 4. MySQLコミットとロールバック
- 5. SQL Serverはトランザクションを検出してコミットしますか?
- 6. タワーはコミットをロールバックしません
- 7. セーブポイントmysqlのロールバックをコミット
- 8. データトランザクションのdbトランザクション(コミットとロールバック)
- 9. 分散データベーストランザクションはコミット/ロールバックを保証されていますか?
- 10. EF5 DbContext.SaveChangesはトランザクションのコミットとロールバックを処理しますか?
- 11. MySQLのコミットとロールバックに失敗しました
- 12. SQLデータベースからのデータベースの復元が遅く、バイナリレプリケーションをテストデータベースにロールバックすることを検討します
- 13. コミット/ロールバックせずに切断されたOracleユーザーは、データベースを変更できません
- 14. は、私はこのクエリで私のデータベースを更新したSQLロールバック・トランザクション
- 15. ネストされたマテリアライズド・ビューはコミット時のアクションを検出しますか?
- 16. Git - 前回のコミットにロールバックする
- 17. Spring Junit Transactionはコミット後にロールバックされません
- 18. PDOロールバックではなくトランザクションをコミットする
- 19. MySQLでは、どのようにBEGIN;ロールバック;コミット。自動コミットに関連する?
- 20. SQL Server - 失敗したトリガーのロールバック
- 21. ステージ3コミット処理中にトランザクションがロールバックされたのはなぜですか?
- 22. EJBロールバックはコンテナ管理では動作しませんトランザクションまたはBean Managamentコミット例外のトランザクション
- 23. hibernateトランザクションはmysql innodbでコミットとロールバックを引き起こします
- 24. MySqlデータベースのバックアップ/ロールバックの作成
- 25. データベースのロールバックによるユニットテスト
- 26. SQLロールバック・トランザクションでは、そこから状態をロールバックしますか?
- 27. MySQLiトランザクションを使用してロールバックしコミットする方法は?
- 28. C#を使用してSQL Server 2005データベースを復元します。ロールバックの問題
- 29. AngularJSでSQLデータベースを検索
- 30. Springバッチでのコミット間隔とロールバックの扱い
私は問題を理解していればわかりません。コミットまたはロールバックのどちらかでトランザクションを終了する必要があります。そのため、あなたは何をしたのか分かりますが、余分な変数でこれを覚えたくありませんか? Txとboolを独自のRememberingTxでラップすると、行数が少し減ります。 GCの質問について:あなたが無しにしてもいなくても問題はありません。メモリが残っていなければ、メモリは再利用されます。そうです:はい、あなたは 'var tx * Tx;スナップ; if cond {tx.Commit; tx = nil} else {tx.Rollback};スナップ;もしtx == nil {コミットされた} else {ロールバックされた} 'しかし、それは醜い感じです。 – Volker
これはまあまあですが、Txがnilでない場合にロールバックを行う遅延関数があります。いったんトランザクションがコミットされると、Txは使用できなくなるので、それをnilに設定する予定です。それはかなりではありませんが、ロールバックを試みて、エラーメッセージをテストすることはどちらかというとかなり簡単ではありません。問題はAFAIKがトランザクションがTxから "完了"されているかどうかをテストする方法がないことです。私はなぜそれがそのように、おそらくパフォーマンスが行われたのか分かりません。 –