Spring Boot @Transaction不会在RuntimeException上回滚

时间:2017-03-02 11:18:36

标签: spring spring-boot transactions spring-jdbc

我有一个Spring启动应用程序,它使用spring-boot-starter-jdbc,Java 8和带有InnoD的MySQL。即使我这样做,应用程序也不会回滚运行时异常:

throw new RuntimeException("Rolling back");

我正在配置我的交易:

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)    

我正在使用Spring Boot Actuator,我可以在Hal Browser中看到这个:

"DataSourceTransactionManagerAutoConfiguration": [
  {
    "condition": "OnClassCondition",
    "message": "@ConditionalOnClass found required classes 'org.springframework.jdbc.core.JdbcTemplate', 'org.springframework.transaction.PlatformTransactionManager'"
  }
],
"DataSourceTransactionManagerAutoConfiguration.DataSourceTransactionManagerConfiguration": [
  {
    "condition": "OnBeanCondition",
    "message": "@ConditionalOnSingleCandidate (types: javax.sql.DataSource; SearchStrategy: all) found a primary bean from beans 'psmDataSource', 'dataSource'"
  }
],
"DataSourceTransactionManagerAutoConfiguration.DataSourceTransactionManagerConfiguration#transactionManager": [
  {
    "condition": "OnBeanCondition",
    "message": "@ConditionalOnMissingBean (types: org.springframework.transaction.PlatformTransactionManager; SearchStrategy: all) did not find any beans"
  }
],
"DataSourceTransactionManagerAutoConfiguration.TransactionManagementConfiguration": [
  {
    "condition": "OnBeanCondition",
    "message": "@ConditionalOnMissingBean (types: org.springframework.transaction.annotation.AbstractTransactionManagementConfiguration; SearchStrategy: all) did not find any beans"
  }
],

我认为这意味着事务管理器已成功配置,因此我不确定为什么交易不会被回滚。是

有什么想法吗?

DAO界面:

public interface IContestService {
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)    
    ContestDTO create(final ElectionEventDTO electionEvent, final ElectionDTO election, final ContestDTO contest, final PollingPlaceDTO pollingPlace, final List<CandidateDTO> candidates);
}

DAO Implemtnation:

@Override
public ContestDTO create(final ElectionEventDTO electionEvent, final ElectionDTO election, final ContestDTO contest, final PollingPlaceDTO pollingPlace, final List<CandidateDTO> candidates) {

    if(electionEvent.getId() == null) {
        getElectionEventService().save(electionEvent);
    }

    if(election.getId() == null) {
        election.setElectionEvent(electionEvent);
        getElectionService().save(election);
    }

    if(election != null) {
        throw new RuntimeException("Rolling back");
    }
    contest.setElection(election);
    getContestDAO().save(contest);

    getCandidateService().save(candidates);

    /**
     * Return the contest
     */
    return contest;
}

application.properties:

logging.file=cm-web.log
logging.level.org.springframework.web=DEBUG

countdb.datasource.url=jdbc:mysql://localhost/countdb
countdb.datasource.username=root
countdb.datasource.password=pass123
countdb.datasource.driver-class-name=com.mysql.jdbc.Driver

psm.datasource.url=jdbc:mysql://localhost/psm
psm.datasource.username=root
psm.datasource.password=password
psm.datasource.driver-class-name=com.mysql.jdbc.Driver

2 个答案:

答案 0 :(得分:1)

您的@Transactional注释位于界面上(这可能是一个坏主意,为什么您希望在合同中显示此类特定于实现的详细信息?)。 Spring Boot默认使用CGLIB代理,所以你根本就没有任何交易。

您可以在@EnableTransactionManagement(proxyTargetClass=false)上添加@SpringBootApplication,以确认这是问题的根本原因。

答案 1 :(得分:0)

所以问题是@Transactional注释是在一个接口上。在接口上放置@Transactional注释是我喜欢做的事情,我已经做了一段时间,但是因为这是一个Spring Boot应用程序,所以它没有用。谢谢你指点我正确的方向。