Spring Boot @Transaction не откатывается на RuntimeException
У меня есть приложение весенней загрузки, которое использует spring-boot-starter-jdbc, Java 8 и MySQL с InnoD. Приложение не откатывает исключения времени выполнения, даже когда я делаю это:
throw new RuntimeException("Rolling back");
Я настраиваю свои транзакции следующим образом:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
Я использую Spring Boot Actuator и вижу это в браузере 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"
}
],
Я предполагаю, что это означает, что Менеджер транзакций был успешно настроен, поэтому я не уверен, почему транзакции не откатываются.
Есть идеи?
Интерфейс 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
2 ответа
Ваш @Transactional
аннотация на интерфейсе (что, возможно, является плохой идеей, почему вы хотите, чтобы такие подробности, связанные с реализацией, отображались в вашем контракте?). Spring Boot по умолчанию использует прокси-сервер CGLIB, поэтому, насколько я вижу, у вас просто нет транзакций.
Можете добавить @EnableTransactionManagement(proxyTargetClass=false)
на ваше @SpringBootApplication
чтобы подтвердить это является основной причиной проблемы.
Таким образом, проблема была в том, что аннотация @Transactional была на интерфейсе. Я предпочитаю размещать аннотации @Transactional на интерфейсе, и я это делал в течение некоторого времени, однако, поскольку это было приложение Spring Boot, оно не работало. Спасибо, что указал мне правильное направление.