提问者:小点点

Spring事务管理


我正在开发spring4 mvc以引入我们的新Web应用程序,目前我们正在使用struts1. x,并希望使用新的框架来支持html5/ajax请求尽可能简单,并希望使用DI和Spring webflow支持的强大功能。

目前在我们的struts1. x应用程序中,db事务管理是在我们自定义的GenericAction中完成的,GenericAction是Action的子类,在GenericAction中,我们从数据源获取连接并切换到子类,然后捕获并回滚任何异常,否则提交,这样数据库原子性(事务管理)就可以在一个地方完成。所有模块操作类都应该扩展GenericAction,以便数据库连接可用并执行与模块相关的内容,完成连接后将在GenericAction中回滚或提交,如上所述。

在Spring,事务的范围以@Transactional注释开始,然后以Service Class中的方法结束,因为服务类标记为@Transactional。这对我来说不是可行的解决方案。我在开始之前阅读了几篇与Spring事务相关的文档,下面是我的问题。我正在使用HibernateTransactionManager作为事务管理器

>

  • 在Web请求或任何类(在单元测试的情况下)的情况下,事务应从拦截器开始。

    在Web请求的情况下,事务应以执行后拦截器结束,在单元测试的情况下,事务应以任何类结束。

    如果引发任何异常,那么我们的HandlerExceptionResolverImpl处理程序将执行,然后应该回滚连接。

    任何解决方法或最佳实践都将不胜感激。

    谢谢Dhorrairaajj


  • 共2个答案

    匿名用户

    在我看来,您可以通过遵循Spring在其org. springframe.jdbc.datassource.DataSourceTransactionManager.doBegin(Object,TransactionDefition)中所做的事情,在当前应用程序上进行最小的更改来实现这一点。详细地说,我认为像以下这样的东西应该可以工作:

    1. 在GenericAction上,从数据源获取连接(正如您已经做的那样)
    2. 通过其持有人将连接与当前数据源绑定:TransactionSyn行吗izationManager. bindResource(getDataSource(),txObject.getConnectionHolder());
    3. 最终,将事务提交为org. springframe.jdbc.datassource.DataSourceTransactionManager.doCommit(DefaultTransactionStatus)。

    无论如何,Spring的http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/transaction/support/TransactionTemplate.html可以帮助实现您想要的任何程序化事务场景。只需要确保正确的事务资源绑定到打开的事务。

    希望这有帮助。

    匿名用户

    感谢您的回复。您的帖子/建议促使您执行以下操作

    我编写了一个名为TxtManager的拦截器,下面是执行事务管理的方法。

    public boolean preHandle(HttpServletRequest request,
        HttpServletResponse response, Object handler) throws Exception
    {
        Session session = sessionFactory.openSession();
        SessionHolder hold = new SessionHolder(
            session);
        TransactionSynchronizationManager.bindResource(sessionFactory, hold);
        // passing null would accept the default transaction definition.
        status = transactionManager.getTransaction(null);
    
        return true;
    }
    
    
    public void afterCompletion(HttpServletRequest request,
        HttpServletResponse response, Object handler, Exception ex)
        throws Exception
    {
        Exception hanlderEx = (Exception) request
            .getAttribute(HandlerExceptionResolverImpl.EXCEPTION_KEY);
    
        if (hanlderEx != null)
        {
            transactionManager.rollback(status);
        }
        else
        {
            transactionManager.commit(status);
        }
    }
    

    在负责处理异常的HandlerExceptionResolverImpl类中,将异常对象放入请求中,并读取相同的异常以回滚或提交到拦截器的后完成方法中。

    在两者之间(preHandler和后完成),我们将使用标准实践来执行模块相关的东西,包括任何其他拦截。可能不支持单元测试,我将检查单元测试的其他替代方案。

    最后我们能够模拟现有的框架工作与您的建议谢谢

    任何改进这一点的建议将不胜感激!!…

    谢谢Dhorrairaajj