【问题标题】:Spring Transaction doesn't Rollback at RuntimeException in @Transactional methodSpring Transaction 不会在 @Transactional 方法中的 RuntimeException 处回滚
【发布时间】:2016-05-03 00:21:04
【问题描述】:

我有这个数据库配置:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = "com.mycompany")
public class DBConfiguration {

    @Bean(destroyMethod = "close")
    public javax.sql.DataSource dataSource() {
        DataSource ds = new DataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost/v2");
        ds.setUsername("java");
        ds.setPassword("mypass");
        ds.setInitialSize(5);
        ds.setMaxActive(10);
        ds.setMaxIdle(5);
        ds.setMinIdle(2);
        ds.setRemoveAbandoned(true);
        ds.setLogAbandoned(true);
        return ds;
    }

    @Bean
    public DataSourceTransactionManager txManager()
    {
        DataSourceTransactionManager tx= new DataSourceTransactionManager(dataSource());
        return tx;
    }

}

问题已更新

我很难理解@Transaction 注解是如何工作的,请考虑这种情况:

@Service
public class FirstService {
    @Transactional  //<--- this annotation seems to be mandatory for my rollback but I don't want it.
    public void test() throws Exception{
        secondService.insert();
    }
}

@Service
public class SecondService {
    @Transactional //<-- I would like to have only this method in transaction
    protected void insert() throws Exception{
        dao.insertEntity(new Entity()); //<<--- this is an SQL insert command
        throw new RuntimeException("Rollback test");
    }
}

测试代码:

@RequestMapping("/test") @ResponseBody
    public void test() throws Exception{
        firstService.test();
    }

道:

public void insertEntity(Entity e) {
        getJdbcTemplate().update(SQL_INSERT,e.getCode(),e.getName());       
    }

这个测试有效,抛出的异常可以回滚事务。

为什么我在 firstService 上省略了@Transaction 注解就没有回滚?

似乎从@Controller 到@Service txmanager 寻找@Transaction 注释,从@Service 到(另一个)@Service 或@Component 它不寻找它。

【问题讨论】:

  • 你可以把你的日志放在调试中,看看@transactional是否附加到你的spring transactionManager。
  • 贴出测试的代码,以及DAO的代码。
  • 你正在使用 InnoDB 表,对吧(或者至少不是 MyISAM)?
  • 当然是 InnoDB :-)
  • 我没有看到事务日志(带调试级别)

标签: java mysql spring jdbc spring-transactions


【解决方案1】:

这对我有用:

@Bean(name = "transactionManager")
    @Primary
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

请更新 spring 版本,可能还有一些日志或调试日志,看看 Transaction 是否有问题

【讨论】:

    【解决方案2】:

    有两个错误。

    第一个错误是 我不能在同一个对象中嵌套两个方法(第一个不是事务性的,第二个事务性的)然后我必须将它分成两个对象(如您在更新的问题中所见)。

    第二个错误是 @Transaction 注释应该应用于公共方法而不是私有或受保护的方法。

    【讨论】:

      猜你喜欢
      • 2017-07-22
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      • 2019-01-27
      • 2013-09-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多