Spring Service @Transactional不会回滚事务Mybatis SqlSession [英] Spring Service @Transactional doesn't rollback transaction Mybatis SqlSession

查看:283
本文介绍了Spring Service @Transactional不会回滚事务Mybatis SqlSession的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标是在失败的情况下回滚所有/任何事务.但这不能按预期工作.

The goal is to rollback all/any transactions in case of failure. But this doesn't work as expected.

我们使用Spring MVC + JMS + Service + Mybatis.在日志中,JMS设置为回滚,但是该行已插入而不是回滚.想知道我在想什么或做错了什么?

We use Spring MVC + JMS + Service + Mybatis. In the logs, the JMS is set to rollback, but the row is inserted and not rollback. Would like to know what I'm missing or doing wrong?

@Transactional标记是最近添加的.因此不确定它是否按预期工作.

The @Transactional tag was added recently. So not sure if it works as expected.

代码:

服务等级:

@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 {
            //LOGGER.debug("in insert::");
            this.dataExchDao.create(dataExch);
            //Empty exception throw to test rollback
            throw new RuntimeException();
        }
    }
}

DAO:

public interface DataExchDaoMybatis
extends NotificationDao {

void create(DataExch dataExch);

}

春季上下文

<bean id="dataExchLogic"  class="com.abc.service.logic.DataExchLogic">
        <property name="dataExchDao" ref="dataExchDao" />
</bean>

EAR/WAR项目Spring Context

<!-- Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />

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

日志:

[31mWARN [0;39m [36mo.s.j.l.DefaultMessageListenerContainer[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.s.j.l.DefaultMessageListenerContainer[0;39m # Successfully refreshed JMS Connection 
[39mDEBUG[0;39m [36mo.s.j.l.DefaultMessageListenerContainer[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.c.i.q.d.m.N.create!selectKey[0;39m # ==>  Preparing: SELECT ID.NEXTVAL FROM DUAL  
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create!selectKey[0;39m # ==> Parameters:  
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create!selectKey[0;39m # <==      Total: 1 
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create[0;39m # ==>  Preparing: INSERT INTO TABLE ( COL1, COL2, COL N) VALUES ( ?, CURRENT_TIMESTAMP, ?, ?, ?, ?, ?, ?)  
[39mDEBUG[0;39m [36mg.c.i.q.d.m.N.create[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.c.i.q.d.m.N.create[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]

控制器代码:

@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已更改:

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);
}

推荐答案

请在根弹簧上下文中放入 transactionManager 配置和 tx:annotation驱动

Please put transactionManager configuration and tx:annotation-driven into root spring context

规则:Root context can see all the beans which Spring created. Child context(any Web Context) can see only its own beans.

在这种特殊情况下,tx:annotation-driven在Web上下文中查找带有@Transactional批注的bean.它找不到任何内容,因为您在根上下文中定义了dataExchLogic.这就是为什么您没有任何交易行为的原因.

In this particular case tx:annotation-driven looks for beans with @Transactional annotation in Web context. It cannot find any because you defined dataExchLogic in root context. That's why you didn't have any transactional behavior.

解决方案意味着将tx:annotation-driven移到根上下文,因为Root Context可以找到在根或任何Web上下文中定义的任何bean.

Solution implies to move tx:annotation-driven to the root context because Root Context can find any bean defined either in root or in any web context.

这篇关于Spring Service @Transactional不会回滚事务Mybatis SqlSession的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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