Я немного раздражен этой проблемой. Давайте проверим, реализовал ли кто-то что-то подобное.
У меня есть веб-приложение java 8 с 8 реализованными WS. Некоторые из этих WS делают вставки и обновления через JDBCTemplate (Hibernate не является выбором из-за требований к производительности), и мне нужно, чтобы они откатились, если выполнение завершается сбоем с исключением.
У меня есть следующая конфигурация источника данных и диспетчера транзакций в файле контекста приложения spring (ресурс jndi в server.xml/context.xml 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" />
С другой стороны, у меня есть уникальная точка доступа к базе данных 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");
}
...
}