Spring 交易管理

Spring transaction management

我正在研究 spring4 mvc 以在我们的新 Web 应用程序中引入,目前我们正在使用 struts1.x 并希望使用新框架来支持 html5/ajax 请求,就像可能并希望使用 DI 的强大功能和 spring webflow 支持。

目前,在我们的 struts1.x 应用程序中,数据库事务管理是在我们的自定义 GenericAction 中完成的,它是 Action 的子class,在 GenericAction 中,我们从数据源获取连接并移交给子classes 然后引发任何异常然后捕获并回滚,否则提交使得数据库原子性(事务管理)在一个地方完成。所有模块操作 classes 都应该扩展 GenericAction,以便数据库连接可用并执行模块相关的东西,完成连接后将在 GenericAction 中回滚或提交,如上所述。

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

  1. 如果是 Web 请求或任何 class(在单元测试的情况下),事务应该从拦截器开始。

  2. 如果是 Web 请求或任何 class 在单元测试的情况下,事务应以拦截器执行后结束。

  3. 如果出现任何异常,我们的 HandlerExceptionResolverImpl 处理程序将执行,然后连接应该回滚。

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

谢谢 多莱拉吉

在我看来,您可以通过遵循 Spring 在其 org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(Object, TransactionDefinition) 中所做的操作,以对当前应用程序进行最小的更改来实现此目的。详细来说,我认为像下面这样的东西应该有效:

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

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

希望对您有所帮助。

感谢您的回复。您的 post/suggestion 驱动器执行以下操作

我编写了一个名为 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);
    }
}

在负责异常处理的HandlerExceptionResolverImplclass中,在请求中放入一个异常对象,在拦截器的afterCompletion方法中读取相同的异常回滚或提交。

在(preHandler 和 afterCompletion)之间,我们将使用标准实践来执行与模块相关的内容,包括任何其他拦截。可能不支持单元测试,我会检查其他替代单元测试。

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

如有任何改进建议,我们将不胜感激!!..

谢谢 多莱拉吉