Spring 启动 @Transaction 不回滚 RuntimeException
Spring Boot @Transaction not rolling back on RuntimeException
我有一个 spring 引导应用程序,它使用 spring-boot-starter-jdbc、Java 8 和 MySQL with InnoD。即使我这样做,应用程序也不会回滚运行时异常:
throw new RuntimeException("Rolling back");
我正在这样配置我的交易:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
我正在使用 Spring 引导执行器,我可以在 Hal 浏览器中看到它:
"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"
}
],
我假设这意味着事务管理器已成功配置,所以我不确定为什么事务没有被滚动 back.Is
有什么想法吗?
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 实现:
@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
你的 @Transactional
注释在一个接口上(这可以说是个坏主意,你为什么要在你的合同中显示这种特定于实现的细节?)。 Spring Boot 默认使用 CGLIB 代理,所以据我所知,您根本没有任何事务。
您可以在 @SpringBootApplication
上添加 @EnableTransactionManagement(proxyTargetClass=false)
以确认这是问题的根本原因。
所以问题是@Transactional 注释在接口上。在界面上放置 @Transactional 注释是我喜欢做的事情,我已经做了一段时间,但是因为这是一个 Spring 启动应用程序,所以它不起作用。感谢您为我指明正确的方向。
我有一个 spring 引导应用程序,它使用 spring-boot-starter-jdbc、Java 8 和 MySQL with InnoD。即使我这样做,应用程序也不会回滚运行时异常:
throw new RuntimeException("Rolling back");
我正在这样配置我的交易:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
我正在使用 Spring 引导执行器,我可以在 Hal 浏览器中看到它:
"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"
}
],
我假设这意味着事务管理器已成功配置,所以我不确定为什么事务没有被滚动 back.Is
有什么想法吗?
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 实现:
@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
你的 @Transactional
注释在一个接口上(这可以说是个坏主意,你为什么要在你的合同中显示这种特定于实现的细节?)。 Spring Boot 默认使用 CGLIB 代理,所以据我所知,您根本没有任何事务。
您可以在 @SpringBootApplication
上添加 @EnableTransactionManagement(proxyTargetClass=false)
以确认这是问题的根本原因。
所以问题是@Transactional 注释在接口上。在界面上放置 @Transactional 注释是我喜欢做的事情,我已经做了一段时间,但是因为这是一个 Spring 启动应用程序,所以它不起作用。感谢您为我指明正确的方向。