まったく複雑ではありません。
-
まず、Springトランザクションマネージャーはトランザクション管理の抽象化にすぎないことを理解する必要があります。あなたの場合、実際のトランザクションはJDBC接続レベルで発生します。
-
すべての
@Transactional
サービスメソッドの呼び出しは、TransactionInterceptor
によってインターセプトされます アスペクト。 -
TransactionIntreceptor
トランザクション管理を現在構成されているAbstractPlatformTransactionManager
実装(JpaTransactionManager
あなたの場合)。 -
JpaTransactionManager
現在実行中のSpringトランザクションをEntityManagerにバインドするため、現在のトランザクションに参加しているすべてのDAOは同じ永続コンテキストを共有します。 -
JpaTransactionManager
単にEntityManager
を使用します トランザクションを制御するためのトランザクションAPI:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction APIは、基になるJDBC接続のコミット/ロールバックメソッドに呼び出しを委任するだけです。
-
トランザクションが完了すると(コミット/ロールバック)、
org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction
呼び出し:transactionCoordinator().getTransactionContext().managedClose();
これにより、Hibernateセッション(エンティティマネージャー)が閉じられます。
-
したがって、基盤となるJDBC接続もトリガーされて閉じられます。
jdbcCoordinator.close();
-
Hibernateには論理JDBC接続ハンドルがあります:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); }
-
論理接続は、現在構成されている接続プロバイダー(
DataSourceConnectionProvider
)にクローズ呼び出しを委任します あなたの場合)、JDBC接続でcloseメソッドを呼び出すだけです:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }
-
他の接続プーリングデータソースと同様に、JDBC接続を閉じると、接続がプールに返されるだけで、物理データベース接続は閉じられません。これは、接続プールのデータソースが、すべての呼び出しをインターセプトし、接続プール処理ロジックにクローズを委任するJDBC接続プロキシを返すためです。
RESOURCE_LOCALトランザクションの場合、 hibernate.connection.provider_disables_autocommit
autocommit
の場合のプロパティ チェックは接続プールによって無効にされました。このようにして、SQLクエリを実行したり、永続コンテキストをフラッシュしたりする前に、データベース接続が遅延して取得されます。