Spring事务无法正常工作+ JAX WS + JDBC [英] Spring transactions not working + JAX WS + JDBC

查看:61
本文介绍了Spring事务无法正常工作+ JAX WS + JDBC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题让我有些生气.让我们检查是否有人实现了类似的东西.

I'm a bit exasperated with this issue. Lets check if someone has implemented something similar.

我有一个实现8 WS的Java 8 Web应用程序.其中一些WS通过JDBCTemplate进行插入和更新(由于性能需求,Hibernate不能选择),如果执行因异常而崩溃,我需要它们回滚.

I have a java 8 web application with 8 WS implemented. Some of this WS, make inserts and updates through JDBCTemplate (Hibernate is not a choice due to performance needs) and i need them to rollback if execution crashes with an exception.

我在spring app上下文文件(Tomcat的server.xml/context.xml中的jndi资源)中具有以下数据源和事务管理器配置:

I have the following configuration of datasource and transaction manager in spring app context file (jndi resource in server.xml/context.xml of Tomcat):

  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/source" />
  </bean>
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
  </bean>

  <tx:annotation-driven transaction-manager="transactionManager" />

另一方面,我对dataBase DBcontroller.class有一个唯一的访问点,该访问点具有用于插入,删除和更新的通用方法:

On the other hand I have a unique accesspoint to the dataBase DBcontroller.class, which has a generic method for inserts, deletes and updates:

private NamedParameterJdbcTemplate jdbcTemplate;
private DataSource datasource;

@Autowired
public void setDataSource(DataSource dataSource) {
    this.datasource = dataSource;
    this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
@Override
public boolean queryForModifying(String query, SqlParameterSource parameters) {

  int modifiedRows= 0;
  try {
      modifiedRows= this.jdbcTemplate.update(query, parameters);
  } catch (Exception e) {
      e.printStackTrace();
      numRegistrosAfectados = 0;
  }
  return (modifiedRows> 0) ? true : false;
}

最后,我以这种方式拥有WS接口:

Finally I have a WS Interface This way:

@WebService
public interface IService{

    @WebMethod
    public method(MethodRequestType request) throws IllegalArgumentException, IllegalAccessException;

}

及其实现:

@WebService(endpointInterface = "com.package.IService")
@HandlerChain(file = "handler-chain.xml")
public class Service implements IService{

    @Autowired
    IDBController dbController;

使用交易"方法:

@Transactional
private boolean inserts(HashMap<String, Object> input, MethodRequestType request) {.....

在非WS项目上应该可以正常工作,但是正如我发现的那样,没有这么简单的方法可以完成这项工作.

It should be working ok on a non WS project, but as I have discovered there is no so easy way for making this work.

首先,我认为它不会回滚,但是现在我很确定它不会创建事务.

First I thought it didn't rollback, but now I'm quite sure it doesn't create transactions.

stackoverflow中有一些类似的帖子,但是都没有解决我的问题.我在Google上搜索了很多,建议的唯一方法是WS-AtomicTransactions,这是我从未听说过的.

There are some similar post in stackoverflow, but none of them fix my problem. I have google it a lot, and the only way suggested is WS-AtomicTransactions, which I have never heard about.

我已经尝试了XML配置文件中的几乎所有内容,甚至尝试以编程方式管理事务,但是由于它是一个连接池,因此我无法将autocommit设置为false,从而可以强制回滚.

I have try almost everything in XML configuration file, I have even tried to manage transactions programatically, but as it is a pool of connections I'm not able to set autocommit to false so that I can force rollbacks.

因为如果对任何人都有用,我为每个WS实现了肥皂处理程序,看起来像这样:

For if it is useful for anyone, I have soap handlers implemented for each WS, that look this way:

public class ServiceHandler implements SOAPHandler<SOAPMessageContext> {

    private SoapFaultHandler soapFaultHandler;

    @Override
    public boolean handleMessage(SOAPMessageContext context) {

        SOAPMessage message = context.getMessage();
        soapFaultHandler = new SoapFaultHandler(message);
        return SoapMessageHandler.handleMessage(context, "Service name", logger);
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return soapFaultHandler.handleFault(context, logger, "ServiceName");

    }
    ...
}

推荐答案

最后我找到了方法! 反正我真的很亲密:

Finally I have found the way! I was really close allways:

  • 事务处理方法(如Gavi所说)必须是公开的(但这不是问题,因为我之前尝试过).

  • The transactional method (as Gavi said) must be public ( but that was not the problem, cause I tried it before).

事务方法应该在其他类中,而不在Webservice注释的类中.

The transactional method should be in other class, not in the Webservice annotated class.

该类需要自动装配,以使其位于Spring上下文中.

This class needs to be autowired so that it is in the Spring context.

在此类中,我自动连接了DbController实例.

In this class I have autowired a DbController instance.

这就是一切.

我的主要问题是,我嘲笑了该类并用"new"实例化了它,而不是让Spring发挥其魔力.

My main problem, was that I mocked this class and instantiated it with a "new", instead letting Spring makes its magic.

感谢您的回应,希望对他人有所帮助!

Thanks for responses, hope to help others!

这篇关于Spring事务无法正常工作+ JAX WS + JDBC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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