我如何在只使用一个连接的hibernate中进行嵌套事务? [英] How do I do nested transactions in hibernate using only one connection?
问题描述
我想解决的问题的上下文:我有一个java spring http拦截器AuditHttpCommunicationInterceptor,用于审计与外部系统的通信。执行通信的HttpClieant用于执行称为DoBusinessLogicSevice的一些业务逻辑的Java服务类。
DoBusinessLogicSevice打开一个新的交易,并使用几个合作者完成大量的工作。
解决问题:无论DoBusinessLogicSevice中的任何操作(意外异常等)的结果如何,我都希望通过AuditHttpCommunicationInterceptor将审计存储在数据库中。 p>
我使用的解决方案:AuditHttpCommunicationInterceptor将以这种方式打开一个新的事务:
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
new TransactionTemplate(platformTransactionManager,transactionDefinition).execute(new TransactionCallbackWithoutResult(){
@Override
protected void doInTransactionWithoutResult(TransactionStatus status){
// do stuff
}
});
一切正常。当DoBusinessLogicSevice的一部分引发异常异常时,它的事务回滚,但AuditHttpCommunicationInterceptor管理将审计存储在数据库中。
这个解决方案产生的问题:AuditHttpCommunicationInterceptor使用一个新的数据库连接。因此,对于每个DoBusinessLogicSevice调用,我需要2个数据库连接。
基本上,我想知道问题的解决方案:在这种情况下,如何使TransactionTemplate暂停当前事务并重新使用新连接。
任何想法? :)
一个想法可能是采取不同的设计方法:删除拦截器并直接创建一个在DoBusinessLogicSevice中使用的AuditingHttpClient(不是在spring中调用),但是我不能这样做,因为我无法访问那里的所有http字段。
Spring支持嵌套事务(propagation =NESTED),但这确实取决于数据库平台,我相信每个数据库平台都能够处理嵌套事务。
我真的不明白从一个池中进行连接,做一个快速的审计事务以及返回连接。
更新:虽然Spring支持嵌套事务,但它看起来像Hibernate没有。如果是这样的话,我会说:去审核另一个连接。
Context of problem I want to solve: I have a java spring http interceptor AuditHttpCommunicationInterceptor that audits communication with an external system. The HttpClieant that does the communication is used in a java service class that does some business logic called DoBusinessLogicSevice. The DoBusinessLogicSevice opens a new transaction and using couple of collaborators does loads of stuff.
Problem to solove: Regardless of the outcome of any of the operations in DoBusinessLogicSevice (unexpected Exceptions, etc) I want audits to be stored in the database by AuditHttpCommunicationInterceptor.
Solution I used: The AuditHttpCommunicationInterceptor will open a new transaction this way:
TransactionDefinition transactionDefinition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
new TransactionTemplate(platformTransactionManager, transactionDefinition).execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// do stuff
}
});
Everything works fine. When a part of DoBusinessLogicSevice throws unexpected exception its transaction is rolled back, but the AuditHttpCommunicationInterceptor manages to store the audit in the database.
Problem that arises from this solution: AuditHttpCommunicationInterceptor uses a new db connection. So for every DoBusinessLogicSevice call I need 2 db connections. Basicly, I want to know the solution to the problem: how to make TransactionTemplate "suspend" the current transaction and reuse the connection for a new one in this case.
Any ideas? :)
P.S. One idea might be to take a different design approach: drop the interceptor and create an AuditingHttpClient that is used in DoBusinessLogicSevice directly (not invoked by spring) but I cannot do that because I cannot access all http fields in there.
Spring supports nested transactions (propagation="NESTED"), but this really depends on the database platform, and I don't believe every database platform is capable of handling nested transactions.
I really don't see what's a big deal with taking connection from a pool, doing a quick audit transaction and returning connection back.
Update: While Spring supports nested transactions, it looks like Hibernate doesn't. If that's the case, I say: go with another connection for audit.
这篇关于我如何在只使用一个连接的hibernate中进行嵌套事务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!