I'm a bit exasperated with this issue. Lets check if someone has implemented something similar.
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.
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" />
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;
}
Finally I have a WS Interface This way:
@WebService
public interface IService{
@WebMethod
public method(MethodRequestType request) throws IllegalArgumentException, IllegalAccessException;
}
with its implementation:
@WebService(endpointInterface = "com.package.IService")
@HandlerChain(file = "handler-chain.xml")
public class Service implements IService{
@Autowired
IDBController dbController;
with a "transactional" method:
@Transactional
private boolean inserts(HashMap<String, Object> input, MethodRequestType request) {.....
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.
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.
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.
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");
}
...
}