Springmvc @Transactional 不回滚

Springmvc @Transactional not rollback

这是我的环境。

  1. mysql5.1(innodb)
  2. spring4.1.6.RELEASE

UserService#test() 方法最后会抛出异常,当完成 table 有新行的请求时。我尝试抛出 Exception 或 RuntimeException 但仍然插入了一个新行 table.

配置

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableCaching
@EnableTransactionManagement
@ComponentScan(basePackages = {
    "com.jpf.crdc.controller", 
    "com.jpf.crdc.service", 
    "com.jpf.crdc.dao", 
    "com.jpf.crdc.log", 
    "com.jpf.crdc.security",
    "com.jpf.crdc.exception"})
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public DataSource dataSource() throws IOException, PropertyVetoException {
        Properties p = PropertiesLoaderUtils.loadProperties(new ClassPathResource("jdbc.properties"));
        //jdbc connection info here ...
        String url = ...
        ...     
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setUrl(url);
        ds.setDriverClassName(driver);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }

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

控制器

@RequestMapping(value = "test", method = RequestMethod.GET)
public JsonView test() {
    userService.test();
    return JsonView.success();
}

服务

@Transactional
public void test() {
    JdbcTemplate jdbc = new JdbcTemplate(ds);
    jdbc.update("insert into t_user(id,editor) value(?,?)", "00000000000000000000000000000001", "abcabc");
    Integer.valueOf("few");
}

调试信息

19:47:22 DEBUG [org.springframework.web.servlet.DispatcherServlet] <DispatcherServlet with name 'dispatcher' processing GET request for [/user/test]>
19:47:22 DEBUG [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] <Looking up handler method for path /user/test>
19:47:22 DEBUG [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] <Returning handler method [public com.jpf.commons.web.JsonView com.jpf.crdc.controller.web.UserController.test()]>
19:47:22 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] <Returning cached instance of singleton bean 'WebUserController'>
19:47:22 DEBUG [org.springframework.web.servlet.DispatcherServlet] <Last-Modified value for [/user/test] is: -1>
19:47:22 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] <Returning cached instance of singleton bean 'transactionManager'>
19:47:22 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Creating new transaction with name [com.jpf.crdc.service.UserService.test]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''>
19:47:22 DEBUG [org.springframework.jdbc.datasource.DriverManagerDataSource] <Creating new JDBC DriverManager Connection to [jdbc:mysql://xxx.xxx.xxx.xxx:3306/test_crdc]>
19:47:25 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Acquired Connection [com.mysql.jdbc.JDBC4Connection@797a7c50] for JDBC transaction>
19:47:25 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Switching JDBC Connection [com.mysql.jdbc.JDBC4Connection@797a7c50] to manual commit>
19:47:25 DEBUG [org.springframework.jdbc.core.JdbcTemplate] <Executing prepared SQL update>
19:47:25 DEBUG [org.springframework.jdbc.core.JdbcTemplate] <Executing prepared SQL statement [insert into t_user(id,editor) value(?,?)]>
19:47:26 DEBUG [org.springframework.jdbc.core.JdbcTemplate] <SQL update affected 1 rows>
19:47:26 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Initiating transaction rollback>
19:47:26 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Rolling back JDBC transaction on Connection [com.mysql.jdbc.JDBC4Connection@797a7c50]>
19:47:27 DEBUG [org.springframework.jdbc.datasource.DataSourceTransactionManager] <Releasing JDBC Connection [com.mysql.jdbc.JDBC4Connection@797a7c50] after transaction>
19:47:27 DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] <Returning JDBC Connection to DataSource>
19:47:27 DEBUG [org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver] <Resolving exception from handler [public com.jpf.commons.web.JsonView com.jpf.crdc.controller.web.UserController.test()]: java.lang.NumberFormatException: For input string: "few">
19:47:27 DEBUG [org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver] <Resolving exception from handler [public com.jpf.commons.web.JsonView com.jpf.crdc.controller.web.UserController.test()]: java.lang.NumberFormatException: For input string: "few">
19:47:27 DEBUG [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] <Resolving exception from handler [public com.jpf.commons.web.JsonView com.jpf.crdc.controller.web.UserController.test()]: java.lang.NumberFormatException: For input string: "few">
19:47:27 DEBUG [org.springframework.web.servlet.DispatcherServlet] <Could not complete request>
java.lang.NumberFormatException: For input string: "few"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:492)
at java.lang.Integer.valueOf(Integer.java:582)
at com.jpf.crdc.service.UserService.test(UserService.java:114)
at com.jpf.crdc.service.UserService$$FastClassBySpringCGLIB$ef3416c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

尝试为您需要的回滚指定异常 @Transactional(rollbackFor=Exception.class)