The goal is to roll back all / any transactions in the event of a failure. But this does not work properly.
We use Spring MVC + JMS + Service + Mybatis. In JMS logs configured to rollback, but the line is inserted, not rollback. I would like to know what am I missing or is something wrong?
The @Transactional tag has recently been added. Therefore, Iโm not sure that it works as expected.
the code:
Class of service:
@Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public class DataExchangeLogic implements DataExchangeService { private DataExchDao dataExchDao; ... @Override public void save(DataExch dataExch) throws ValidationException { if (dataExch.getId() != null && dataExch.getId() > 0) { this.dataExchDao.update(dataExch); } else {
DAO:
public interface DataExchDaoMybatis extends NotificationDao { void create(DataExch dataExch); }
Spring Context
<bean id="dataExchLogic" class="com.abc.service.logic.DataExchLogic"> <property name="dataExchDao" ref="dataExchDao" /> </bean>
EAR / WAR Spring Project
<bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" /> <tx:annotation-driven transaction-manager="transactionManager" />
Logs:
[31mWARN [0;39m [36mo.sjlDefaultMessageListenerContainer[0;39m # Setup of JMS message listener invoker failed for destination 'queue://REQUEST?priority=1&timeToLive=500000' - trying to recover. Cause: Transaction rolled back because it has been marked as rollback-only org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:720) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:240) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1142) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1134) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1031) at java.lang.Thread.run(Thread.java:745) [34mINFO [0;39m [36mo.sjlDefaultMessageListenerContainer[0;39m # Successfully refreshed JMS Connection [39mDEBUG[0;39m [36mo.sjlDefaultMessageListenerContainer[0;39m # Received message of type [class com.ibm.ws.sib.api.jms.impl.JmsTextMessageImpl] from consumer [com.ibm.ws.sib.api.jms.impl.JmsQueueReceiverImpl@6ca01c74] of transactional session [com.ibm.ws.sib.api.jms.impl.JmsQueueSessionImpl@3ac3b63] Creating a new SqlSession Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@206ee277] JDBC Connection [com.ibm.ws.rsadapter.jdbc.WSJdbcConnection@19b89f0c] will be managed by Spring [39mDEBUG[0;39m [36mg.ciqdmNcreate!selectKey[0;39m # ==> Preparing: SELECT ID.NEXTVAL FROM DUAL [39mDEBUG[0;39m [36mg.ciqdmNcreate!selectKey[0;39m # ==> Parameters: [39mDEBUG[0;39m [36mg.ciqdmNcreate!selectKey[0;39m # <== Total: 1 [39mDEBUG[0;39m [36mg.ciqdmNcreate[0;39m # ==> Preparing: INSERT INTO TABLE ( COL1, COL2, COL N) VALUES ( ?, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?) [39mDEBUG[0;39m [36mg.ciqdmNcreate[0;39m # ==> Parameters: 468(Integer), SYSTEM(String), 2017-03-01 00:00:00.0(Timestamp), 2017-03-16 00:00:00.0(Timestamp), true(Boolean), test 112(String), ALL(String) [39mDEBUG[0;39m [36mg.ciqdmNcreate[0;39m # <== Updates: 1 Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@206ee277] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@206ee277] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@206ee277]
EDIT 1:
Controller Code:
@ResourceMapping(value = "addNewDEURL") public void addNewDE(@ModelAttribute(value = "dataObject") final DataExch dataExch, final BindingResult bindingResult, final ResourceResponse response) { if (!bindingResult.hasErrors()) { try { dataExchangeService.save(dataExch); } catch (final ValidationException e) { logger.error("A validation exception occurred.", e); } } else { logger.error(bindingResult.getAllErrors().get(0) .getDefaultMessage()); } }
DAO changed:
public class DataExchDaoMybatis extends BaseDaoImpl implements DataExchDao { public void create(DataExch dataExch) { doSimpleInsert("insertDE", dataExch); } }
BaseDaoImpl:
public void doSimpleInsert(String queryId, Object o) { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert(queryId, o); }