Hibernate APIには、プロパティ hibernate.connection.autocommit があり、trueに設定できます。
しかし、APIでは、次のように設定することは推奨されないと述べています。
JDBCプール接続の自動コミットを有効にします(推奨されません)。
なぜ推奨されないのですか?このプロパティをtrueに設定すると、どのような悪影響がありますか?
デフォルトでは、自動コミット値はfalseであるため、トランザクションを明示的にコミットする必要があります。これが、変更がデータベースに反映されない理由かもしれません。そうでなければ、コミットする前にフラッシュを試して変更を強制できます。
セッションを閉じると、暗黙的にデータベースでコミットされます[実装によって異なります]。
カスケードトランザクションがあり、アトミック性をロールバックする必要がある場合、トランザクションを制御する必要があります。その場合、自動コミットはfalseである必要があります。
自動コミットをtrueに設定するか、トランザクションを明示的に処理します。
ここ が適切な説明です。
Hibernateフォーラム これに関連。
私の理解では、Hibernateが自動コミットする場合、途中で失敗したフラッシュはロールバックされません。不完全/破損したオブジェクトグラフが表示されます。
何かの自動コミットをオンにした接続が必要な場合は、いつでも新しく作成されたSession
をアンラップして、基になるJDBC接続setAutocommit(true)
を取得し、JDBC APIを介して作業を行うことができますsetAutocommit(false)
、およびセッションを閉じます。 not既に何かを行ったSession
でこれを行うことをお勧めします。
すべてのデータベースステートメントは、物理トランザクションのコンテキスト内で実行されます トランザクション境界を明示的に宣言しない場合でも (BEGIN/COMMIT/ROLLBACK)。
トランザクション境界を宣言しない場合、各ステートメントは個別のトランザクションで実行する必要があります。これにより、ステートメントごとに1つの接続を開いたり閉じたりすることさえあります。
サービスを@Transactionalとして宣言すると、トランザクション期間全体で1つの接続が提供され、すべてのステートメントはその単一の分離接続を使用します。これは、最初に明示的なトランザクションを使用しないよりもはるかに優れています。大規模なアプリケーションでは、多数の同時リクエストが発生する可能性があり、 データベース接続取得リクエストレートの削減 は、アプリケーション全体のパフォーマンスを確実に向上させます。
したがって、経験則は次のとおりです。
1つのクエリのみを実行する読み取り専用トランザクションがある場合、それらの自動コミットを有効にできます。
複数のステートメントを含むトランザクションがある場合、すべての操作を単一の作業単位で実行し、接続プールに余分な圧力をかけたくないため、自動コミットを無効にする必要があります。
セッションごとのセッションアンチパターンを使用しないでください。単一のスレッドで単純なデータベース呼び出しごとにセッションを開いたり閉じたりしないでください。データベーストランザクションについても同様です。アプリケーションのデータベース呼び出しは、計画されたシーケンスを使用して行われます。それらはアトミックな作業単位にグループ化されます。また、このモードはアドホックSQLコンソール作業を目的としているため、アプリケーションではすべてのSQLステートメントが役に立たないことを意味します。 Hibernateは、自動コミットモードを直ちに無効にするか、アプリケーションサーバーが無効になることを予期します。データベーストランザクションは決してオプションではありません。データベースとのすべての通信は、トランザクション内で発生する必要があります。多くの小さなトランザクションは、明確に定義された1つの作業単位よりもパフォーマンスが低い可能性が高いため、データの読み取りの自動コミット動作は避ける必要があります。後者は、保守性と拡張性も向上しています。