一点也不复杂。
首先,您需要了解Spring事务管理器只是事务管理的抽象。在您的情况下,实际的事务发生在JDBC连接级别。
Aspect
@Transactional
将拦截所有服务方法调用TransactionInterceptor
。该
TransactionIntreceptor
委托事务管理当前的配置AbstractPlatformTransactionManager
实现(JpaTransactionManager
你的情况)。JpaTransactionManager
会将当前正在运行的Spring事务绑定到EntityManager,因此参与当前事务的所有DAO共享相同的持久性上下文。JpaTransactionManager
只需使用EntityManager
Transaction API来控制交易即可:
EntityTransaction tx = txObject.getEntityManagerHolder().getEntityManager().getTransaction(); tx.commit();
JPA Transaction API只是将调用委托给基础的JDBC Connection提交/回滚方法。
- 事务完成(提交/回滚)后,将
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(); }- 逻辑连接将close调用委派给当前配置的连接提供程序(
DataSourceConnectionProvider
在您的情况下),该提供程序仅在JDBC连接上调用close方法:
@Override public void closeConnection(Connection connection) throws SQLException { connection.close(); }- 像任何其他连接池DataSource一样,JDBC连接关闭只会将连接返回到池,而不会关闭物理数据库连接。这是因为连接池数据源返回一个JDBC连接代理,该代理拦截所有调用并将结束事务委托给连接池处理逻辑。
您还可以找到关于此主题的更多细节,以及为什么需要设置
hibernate.connection.provider_disables_autocommit与Hibernate属性在这篇文章。



