Search code examples
javaspringtransactional

Springmvc @Transactional not rollback


This is my environment.

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

The UserService#test() method has a exception will throw on finally, when finish the request that table has a new row. I try throw Exception or RuntimeException but still a new row inserted into table.

Config

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

Controller

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

Service

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

Debug Info

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$$8ef3416c.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

Solution

  • Try specifing the exception for what you need a rollback like that @Transactional(rollbackFor=Exception.class)