4

I have a problem with Spring Boot 2.0.0. When I throw an RuntimeException it is not rollback the transaction. I was using Spring Boot 1.5.9 with the same settings and it worked. It just migrated to Spring Boot 2 and stopped working.

My Configuration class:

@Configuration
@EnableJpaRepositories(basePackages = "com.test.repository")
@EnableTransactionManagement
public class DatabaseConfiguration {

    public static final String MODEL_PACKAGE = "com.test.model";

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() throws SQLException {
        org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl(this.url);
        dataSource.setUsername(this.username);
        dataSource.setPassword(this.password);
        return dataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

}

My Business class:

@Service
public class TestBusinessImpl implements TestBusiness {

    @Override
    @Transactional
    public void save(final Test test) {
        this.testRepository.save(test);

        throw new RuntimeException("Test rollback");
    }

}

Does anyone know what may be happening?

Murilo Locatelli
  • 178
  • 3
  • 13
  • As a side note you have configured a connection pool without any connection validation. You should at least use `setTestOnBorrow(true)` which is done by Spring in autoconfiguration. Also Spring Boot 2.0 switched to HikariCP as preferred pool. – Karol Dowbecki Mar 24 '18 at 21:39
  • I've simplified to post the configuration here. I tested with HikariCP to, but no success. Transaction continues without rollback. – Murilo Locatelli Mar 24 '18 at 21:55
  • Do you see transactions working when you log with `org.springframework.transaction.interceptor=trace`? Is there any transactional activity at all e.g. opening transactions? – Karol Dowbecki Mar 24 '18 at 22:04
  • What happens if you put transaction in the bean managed transaction manager? – Roman C Mar 24 '18 at 23:22
  • @KarolDowbecki Yes, there are transactional activity: 2018-03-25 02:10:51.202 TRACE 24185 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [com.test.business.impl.TestBusinessImpl.save] / 2018-03-25 02:10:51.221 TRACE 24185 --- [nio-8080-exec-3] o.s.t.i.TransactionInterceptor : Getting transaction for [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save] – Murilo Locatelli Mar 25 '18 at 21:27

1 Answers1

10

Which dialect are you using? You must be specifying spring.jpa.properties.hibernate.dialect

Springboot 2.0 @Transaction doesn't get supported by org.hibernate.dialect.MySQL5Dialect

Rather use org.hibernate.dialect.MySQL5InnoDBDialect

user3531698
  • 126
  • 2
  • 6
  • MySQL supports multiple storage engines, InnoDB is one. So your solution will probably only work when you've matching storage engine set. Reference - https://dev.mysql.com/doc/refman/8.0/en/storage-engine-setting.html – masT Apr 24 '18 at 09:34
  • InnoDB is the most widely used storage engine with transaction support. It is an ACID compliant storage engine. It supports row-level locking, crash recovery and multi-version concurrency control. It is the only engine which provides foreign key referential integrity constraint. Oracle recommends using InnoDB for tables except for specialized use cases. – masT Apr 24 '18 at 09:36
  • I changed dialect to MySQL5InnoDBDialect and it worked. Thanks @user3531698 – Murilo Locatelli May 03 '18 at 00:38
  • @user3531698: It is working for me as well. I was stuck in this issue for hours. Finally got it done. – Richa Dec 21 '18 at 06:43