Search code examples
springmybatistransactional

Java Spring @Transactional method not rolling back when throw exception


My config code here:

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
@PropertySource(value="classpath:datasource.properties")
public class DataSourceConfig {

    @Autowired private Environment env;

    @Bean(destroyMethod="close")
    public BasicDataSource dataSource() {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(env.getProperty("db.driverClass"));
        ds.setUrl(env.getProperty("db.url"));
        ds.setUsername(env.getProperty("db.username"));
        ds.setPassword(env.getProperty("db.password"));
        ds.setInitialSize(Integer.valueOf(env.getProperty("db.initialSize")));
        return ds;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

The @Transactional method:

@Override
    @Transactional
    public void create(String orderid, String type, String userid,
            String comment) throws Exception {
        log.info("### orderid={}, type={}, userid={}, comment={}", 
                orderid, type, userid, comment);
        OrderActivity orderActivity = new OrderActivity();
        orderActivity.setActivityid(SeqUtil.produceOrderActivityid());
        orderActivity.setComment(comment);
        orderActivity.setOperator(userid);
        orderActivity.setOrderid(orderid);
        orderActivity.setType(type);
        orderactivityDao.insert(orderActivity);
        //FIXME just for test
        if(OrderConstant.ACTIVITY_CANCEL.equals(type)){
            throw new RuntimeException();
        }
        log.info("###orderActivity=[{}]", orderActivity);
    }

In the method create, when type is ACTIVITY_CANCEL, then throw an exception. But this activity is also be inserted into database, not rollback. Why?


Solution

  • I got it. I put AppConfig and b in DataSourceConfig different context. Changed the code like this:

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {AppConfig.class, DataSourceConfig.class, MybatisConfig.class, SecurityConfig.class };
    
    }
    
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { MCVConfig.class};
    }
    

    Then everything is ok.