質問

データベースからの読み取りにトランザクションを使用することについては、非常に異なる意見があるようです。

DeveloperWorksの記事トランザクション戦略:モデルからの引用と戦略の概要

  

なぜトランザクションが必要なのか   あなたはデータを読んでいるだけですか?答え   しないということです。開始   読み取り専用を実行するトランザクション   操作は、オーバーヘッドを追加します   スレッドを処理し、共有することができます   データベースの読み取りロック(依存   使用しているデータベースの種類   そして、分離レベルが設定されているもの   to)。

反対の意見として、Hibernateドキュメントからの次の引用があります非トランザクションデータアクセスと自動コミットモード

  

推奨事項は、   アプリケーションの自動コミットモード、および   読み取り専用トランザクションのみを適用する   明らかなパフォーマンスがある場合   利益または将来のコード変更時   ありそうもない。常に好む   グループ化する通常のACIDトランザクション   データアクセス操作、   読むかどうかに関係なく   データを書き込みます。

EclipseLinkメーリングリストにも同様の議論がありますこちら

では、真実はどこにあるのでしょうか?ベストプラクティスを読むためのトランザクションはそうですか?両方が実行可能なソリューションである場合、トランザクションを使用するための基準は何ですか?

私が見る限り、分離レベルが「読み取りコミット」よりも高い場合にのみ違いが生じます。これは正しいですか?

経験と推奨事項は何ですか?

役に立ちましたか?

解決

Steven Devijverは、操作がデータベースの読み取りのみを行う場合でも、トランザクションを開始するいくつかの正当な理由を提供しました。

  • タイムアウトまたはロックモードの設定
  • 分離レベルを設定

標準SQLでは、現在進行中のトランザクションがない場合、クエリでさえ新しいトランザクションを開始する必要があります。それが起こらないDBMSがあります-例えば、自動コミットモードを持つもの(ステートメントはトランザクションを開始し、ステートメントが完了するとすぐにコミットします)。他のDBMSは、デフォルトでステートメントをアトミック(効果的に自動コミット)にしますが、「BEGIN WORK」などのステートメントで明示的なトランザクションを開始し、次のCOMMITまたはROLLBACK(IBM Informix Dynamic Serverがそのような場合-データベースがMODEでない場合) ANSI)。

決してロールバックしないというアドバイスについてはわかりません。読み取り専用トランザクションに違いはなく、DBAに迷惑をかける程度であれば、ROLLBACKを避けるほうがよいでしょう。ただし、COMMITを実行せずにプログラムが終了する場合、DBMSは不完全なトランザクションでROLLBACKを実行する必要があります-データベースを変更した場合、および(簡単にするため)データのみを選択した場合でもです。

全体として、一連の操作のデフォルトの動作を変更する場合は、トランザクションが読み取り専用であってもトランザクションを使用します。デフォルトの動作に満足している場合、トランザクションを使用することは重要ではありません。コードをDBMS間で移植できるようにする場合は、トランザクションが必要になると想定するのが最善です。

他のヒント

まず、これは時期尚早な最適化のように聞こえます。スティーブンが指摘したように、ほとんどの正気なデータベースはとにかくあなたをトランザクションに入れます、そして彼らが本当にしているのは各ステートメントの後にコミットを呼び出すことです。したがって、その観点からは、各ステートメントが新しいトランザクションを開始する必要があるため、自動コミットのパフォーマンスが低下する可能性があります。またはそうでないかもしれません。ベンチマークだけがわかり、アプリケーションに大きな違いをもたらすことはないと思います。

常にトランザクションを使用する理由の1つは、保護の一貫性です。 「必要」な場合にのみ手動でトランザクションを宣言することにいじり始めた場合その後、重要なときに忘れてしまいます。または、おそらく読み取り専用の操作のセットは、後のプログラマがそれが想定されていることに気づかなかったか、コードが非表示の書き込みを持つ関数を呼び出すために突然ではありません。たとえば、自動コミットしないようにコマンドラインデータベースクライアントを構成します。これは、削除クエリを太らせてもロールバックできることを意味します。

指摘したように、分離レベルがあります。これにより、他のプロセスがデータの間にデータを書き込んだかどうかを心配することなく、複数の読み取りを実行して、読み取りを効果的にアトミックにすることができます。これにより、競合状態をデバッグするのに1時間もかかりません。

そして最後に、トランザクションを読み取り専用に設定することができます。これは仮定をチェックし、何かが書き込もうとするとエラーになります。

ここにすべてをまとめた素晴らしい記事があります。 。詳細はOracle固有ですが、概念は一般的です。

デフォルトのタイムアウト以外のクエリに特定のタイムアウトを設定する場合、または分離レベルを変更する場合は、読み取り専用操作にトランザクションが必要です。

また、例外を知らないすべてのデータベースは、各クエリに対してトランザクションを内部的に開始します。一般に、ロールバックが必要でない場合、トランザクションをロールバックしないと考えられます。

DBAはロールバックアクティビティを監視している可能性があり、その場合、デフォルトのロールバック動作はそれらを困らせます。

したがって、トランザクションは開始するかどうかに関係なく使用されます。必要ない場合は起動しないでください。ただし、読み取り専用操作でロールバックを実行しないでください。

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