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
@Transactional
panggilan metode layanan dicegat olehTransactionInterceptor
Aspek. -
TransactionIntreceptor
mendelegasikan manajemen transaksi ke konfigurasi saat iniAbstractPlatformTransactionManager
implementasi (JpaTransactionManager
dalam kasus Anda). -
JpaTransactionManager
akan mengikat transaksi Spring yang berjalan saat ini ke EntityManager, sehingga semua DAO yang berpartisipasi dalam transaksi saat ini memiliki Konteks Persistence yang sama. -
JpaTransactionManager
cukup gunakanEntityManager
API 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.JdbcTransaction
panggilan: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 (
DataSourceConnectionProvider
dalam 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.