選択のみを行うトランザクションで、コミットとロールバックに違いはありますか?

StackOverflow https://stackoverflow.com/questions/198108

質問

会社で使用している社内アプリケーションフレームワークでは、どのコマンドもデータベースを変更しないことがわかっていても、すべてのSQLクエリをトランザクションに入れる必要があります。セッションの終わりに、接続を閉じる前に、トランザクションをコミットして適切に閉じます。ロールバックした場合、特に速度の面で特に違いはあったのでしょうか。

私はOracleを使用していますが、他のデータベースも同様の動作をしていると思います。また、トランザクションを開始する要件については何もできません。コードベースのその部分は手に負えません。

役に立ちましたか?

解決

データベースは、多くの場合、変更前イメージジャーナル(トランザクション前)または変更後イメージジャーナル(トランザクション完了時の状態)のいずれかを保持します。変更前イメージを保持する場合は、復元する必要がありますロールバック中。更新後イメージを保持している場合、コミットのイベントでデータを置き換える必要があります。

Oracleには、ジャーナルとロールバックの両方のスペースがあります。トランザクションジャーナルは、後でDBライターによって書き込まれるブロックを蓄積します。これらは非同期であるため、DBライターに関連するものはほとんどトランザクションに影響を及ぼしません(キューがいっぱいになった場合、待機する必要があります)。

クエリのみのトランザクションであっても、Oracleのロールバック領域にトランザクションの記録保持が少しあるとは思います。ロールバックには、実際にロールバックするものが何もないと判断する前に、Oracle側で何らかの作業が必要であると思われます。そして、これはトランザクションと同期していると思います。ロールバックが完了するまで、実際にロックを解除することはできません。 [はい、トランザクションで何も使用していないことはわかっていますが、ロックの問題が原因でロールバックを完全に解放する必要があると思うので、すべてのロックを解放してからロールバックを完了します。]

一方、コミットは予想される結果とほぼ同じであり、ロールバック領域の破棄は少し速くなると思われます。トランザクションエントリを作成していないので、db writerは目覚めて、何もすることがないことを確認して発見することさえありません。

また、コミットは高速になるかもしれませんが、違いは小さいと思います。非常にマイナーなため、並べて比較しても測定できない場合があります。

他のヒント

この場合、COMMITとROLLBACKの間に違いはないという以前の回答に同意します。 COMMITに何もないことを判断するのに必要なCPU時間と、ROLLBACKに何もないことを判断するのに必要なCPU時間には、ごくわずかな違いがあるかもしれません。しかし、それがごくわずかな違いであれば、それについては安全に忘れることができます。

ただし、単一のトランザクションのコンテキストで大量のクエリを実行するセッションと、一連のトランザクションのコンテキストで同じクエリを実行するセッションとの間には違いがあることに注意してください。

クライアントがトランザクションを開始し、クエリを実行し、COMMITor ROLLBACKを実行し、次に2番目のトランザクションを開始して2番目のクエリを実行する場合、2番目のクエリが最初のクエリと同じデータベース状態を監視する保証はありません。データの単一の一貫したビューを維持することが重要な場合があります。データの最新のビューを取得することが重要な場合があります。それはあなたが何をしているかに依存します。

私は知っています、OPはこの質問をしませんでした。しかし、一部の読者は心の奥底でそれを求めているかもしれません。

一般に、COMMITはROLLBACKよりもはるかに高速ですが、何もしなかった場合は事実上同じです。

ドキュメントには次のように記載されています:

  • Oracleデータベースから切断する前に、アプリケーションプログラムのすべてのトランザクションを、最後のトランザクションを含むCOMMITまたはROLLBACKステートメントで明示的に終了することをお勧めします。トランザクションを明示的にコミットせず、プログラムが異常終了した場合、最後のコミットされていないトランザクションは自動的にロールバックされます。ほとんどのOracleユーティリティおよびツールからの通常の終了により、現在のトランザクションがコミットされます。 Oracleプリコンパイラプログラムからの通常の出口はトランザクションをコミットせず、Oracleデータベースに依存して現在のトランザクションをロールバックします。

http://download.oracle .com / docs / cd / B28359_01 / server.111 / b28286 / statements_4010.htm#SQLRF01110

どちらか一方を行うことを選択したい場合は、何もしないのと同じことを行い、そのままコミットすることもできます。

まあ、OracleでSELECTが返すものを考慮する必要があります。 2つのモードがあります。デフォルトでは、SELECTステートメントが実行を開始した瞬間に、SELECTがデータを参照したときにデータが返されます(これは、デフォルトのトランザクションモードであるREAD COMMITTED分離モードのデフォルトの動作です)。そのため、SELECTの発行後にUPDATE / INSERTが実行された場合、結果セットには表示されません。

これは、2つの結果セットを比較する必要がある場合に問題になる可能性があります(たとえば、総勘定元帳アプリの負債とクレジット)。そのために、2番目のモードがあります。このモードでは、SELECTは現在のトランザクションが開始された瞬間にデータを返します(読み取り専用およびシリアライズ可能分離レベルのデフォルトの動作)。

したがって、少なくとも時々トランザクションでSELECTを実行する必要があります。

DMLを実行していないので、OracleのCOMMITとROLLBACKに違いはないと思います。いずれにしても、何もすることはありません。

Commitの方が効率的だと思います。一般に、ほとんどのDBトランザクションがコミットされると予想されるためです。したがって、DBはこの場合に最適化されると考えられます(ロールバックにより効率的にしようとするのではなく)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top