Ini tidak rumit sama sekali.
-
Pertama, Anda perlu memahami bahwa manajer transaksi Spring hanyalah abstraksi manajemen transaksi. Dalam kasus Anda, transaksi sebenarnya terjadi di tingkat Koneksi JDBC.
-
Semua
@Transactionalpanggilan metode layanan dicegat olehTransactionInterceptorAspek. -
TransactionIntreceptormendelegasikan manajemen transaksi ke konfigurasi saat iniAbstractPlatformTransactionManagerimplementasi (JpaTransactionManagerdalam kasus Anda). -
JpaTransactionManagerakan mengikat transaksi Spring yang berjalan saat ini ke EntityManager, sehingga semua DAO yang berpartisipasi dalam transaksi saat ini memiliki Konteks Persistence yang sama. -
JpaTransactionManagercukup gunakanEntityManagerAPI Transaksi untuk mengendalikan transaksi:EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction API hanya mendelegasikan panggilan ke metode commit/rollback Koneksi JDBC yang mendasarinya.
-
Ketika transaksi selesai (commit/rollback),
org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionpanggilan:transactionCoordinator().getTransactionContext().managedClose();
yang memicu penutupan Sesi Hibernasi (Pengelola Entitas).
-
Oleh karena itu, koneksi JDBC yang mendasarinya juga dipicu untuk ditutup:
jdbcCoordinator.close(); -
Hibernate memiliki pegangan koneksi JDBC logis:
@Override public Connection close() { LOG.tracev( "Closing JDBC container [{0}]", this ); if ( currentBatch != null ) { LOG.closingUnreleasedBatch(); currentBatch.release(); } cleanup(); return logicalConnection.close(); } -
Koneksi logis mendelegasikan panggilan dekat ke penyedia koneksi yang saat ini dikonfigurasi (
DataSourceConnectionProviderdalam kasus Anda), yang hanya memanggil metode tutup pada koneksi JDBC:@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); } -
Seperti dataSource pooling koneksi lainnya, koneksi JDBC close hanya mengembalikan koneksi ke pool dan tidak menutup koneksi database fisik. Itu karena kumpulan koneksi DataSource mengembalikan proxy Koneksi JDBC yang memotong semua panggilan dan mendelegasikan penutupan logika penanganan kumpulan koneksi.
Perhatikan bahwa untuk transaksi RESOURCE_LOCAL, Anda juga harus menyetel hibernate.connection.provider_disables_autocommit
properti jika autocommit cek dinonaktifkan oleh kumpulan koneksi. Dengan cara ini, koneksi database akan diperoleh dengan lambat sebelum mengeksekusi kueri SQL atau menghapus Konteks Persistensi.