我对这个问题有点恼火。让我们检查一下是否有人实现了类似的东西。
我有一个 java 8 Web 应用程序,实现了 8 WS。其中一些 WS 通过 JDBCTemplate 进行插入和更新(由于性能需求,Hibernate 不是一个选择),如果执行因异常而崩溃,我需要它们回滚。
我在 Spring 应用程序上下文文件(Tomcat 的 server.xml/context.xml 中的 jndi 资源)中对数据源和事务管理器进行了以下配置:
<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" />
另一方面,我有一个对数据库 DBcontroller.class 的唯一访问点,它有一个用于插入、删除和更新的通用方法:
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 接口:
@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 项目上正常工作,但正如我发现的那样,没有那么简单的方法可以完成这项工作。
起初我以为它没有回滚,但现在我很确定它不会创建事务。
stackoverflow 上有一些类似的帖子,但没有一个能解决我的问题。我用谷歌搜索了很多,建议的唯一方法是 WS-AtomicTransactions,我从未听说过。
我已经尝试了 XML 配置文件中的几乎所有内容,我什至尝试以编程方式管理事务,但由于它是一个连接池,我无法将自动提交设置为 false,以便我可以强制回滚。
如果它对任何人都有用,我为每个 WS 实现了肥皂处理程序,如下所示:
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");
}
...
}