我如何在只使用一个连接的hibernate中进行嵌套事务? [英] How do I do nested transactions in hibernate using only one connection?

查看:57
本文介绍了我如何在只使用一个连接的hibernate中进行嵌套事务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想解决的问题的上下文:我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆