Reputation: 556
I have a spring boot application that is using spring-boot-starter-jdbc, Java 8 and MySQL with InnoD. The application isn't rolling back Runtime Exceptions, even when I do this:
throw new RuntimeException("Rolling back");
I am configuring my Transactions like this:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
I am using the Spring Boot Actuator and I can see this in the 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"
}
],
I'm assuming that this means that a Transaction Manager has been successfully configured, so I'm not sure why the transactions aren't being rolled back.Is
Any ideas?
DAO Interface:
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
Upvotes: 2
Views: 4731
Reputation: 556
So the problem was that the @Transactional annotation was on an interface. Putting @Transactional annotations on an interface is something I prefer to do and I have done for some time, however as this was a Spring Boot app it didn't work. Thanks for pointing me in the right direction.
Upvotes: 0
Reputation: 33091
Your @Transactional
annotation is on an interface (which arguably is a bad idea, why would you want such implementation-specific details to show up in your contract?). Spring Boot uses CGLIB proxy by default so you simply don't have any transaction at all as far as I can see.
You can add @EnableTransactionManagement(proxyTargetClass=false)
on your @SpringBootApplication
to confirm this is the root cause of the issue.
Upvotes: 1