解决的问题上下文:我有一个java spring http拦截器AuditHttpCommunicationInterceptor,用于审计与外部系统的通信。进行通信的 HttpClieant 用于执行一些称为 DoBusinessLogicSevice 的业务逻辑的 java 服务类。DoBusinessLogicService打开一个新的交易,使用几个协作者做很多事情。
问题:无论DoBusinessLogicService中任何操作的结果如何(意外异常等),我都希望审计通过AuditHttpCommunicationInterceptor存储在数据库中。
我使用的解决方案:AuditHttpCommunicationInterceptor将以这种方式打开一个新事务:
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
new TransactionTemplate(platformTransactionManager, transactionDefinition).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// do stuff
}
});
一切正常。当DoBusinessLogicSvice的一部分抛出意外异常时,其事务将回滚,但AuditHttpCommunicationInterceptor设法将审计存储在数据库中。
此解决方案引起的问题:AuditHttpCommunicationInterceptor 使用新的数据库连接。因此,对于每个DoBusinessLogic服务调用,我需要2个数据库连接。基本上,我想知道问题的解决方案:在这种情况下,如何使TransactionTemplate"挂起"当前事务并重用新事务的连接。
有什么想法吗?:)
附言一个想法可能是采取不同的设计方法:删除拦截器并创建一个直接在DoBusinessLogicSvice中使用的AuditingHttpClient(不是由spring调用的),但我不能这样做,因为我无法访问那里的所有http字段。
Spring 支持嵌套事务(propagation="NESTED"),但这实际上取决于数据库平台,我不相信每个数据库平台都能够处理嵌套事务。
我真的看不出从池中获取连接、进行快速审计事务并返回连接有什么大不了的。
更新:虽然Spring支持嵌套事务,但看起来Hibernate不支持。如果是这样的话,我说:去另一个连接进行审计。