Skip to content
Advertisement

SpringBoot – @Transactional – not opening transaction

I am trying to use transaction in SpringBoot app , for some reason it just doesn’t work. Below is the code for the sample app. I have a rest api in MyRestController.java which invokes DBService.hello() method. In hello() method I insert a row into a table using JOOQ. I see transaction is NOT being created , after further debugging I see that DataSourceTransactionManager.doBegin() method is not being invoked, which explains why transaction is not created. Can any one point what is wrong with this simple code?

@SpringBootApplication
    @EnableTransactionManagement(proxyTargetClass = true)
    public class JooqtransactionApplication {
        public static void main(String[] args) {
            ConfigurableApplicationContext context = SpringApplication.run(JooqtransactionApplication.class, args);
        }
    }

MyRestController.java

    @RestController
    public class MyRestController {
        @Autowired
        DBService DBService;
    
        @GetMapping("/callHello")
        void invokeHello()
        {
            DBService.hello();
        }
    }

DBService.java

@Service
public class DBService {
    @Autowired
    DSLContext ctx;

    @Transactional()
    void hello() {
        ctx.insertInto(Prospectiveclient.PROSPECTIVECLIENT).values("val1", "val2", "val3", "", LocalDateTime.now()).execute();
    }
}

Creation of Beans

    @Configuration
    public class GlobalConfiguration {
        @Autowired
        private Environment environment;
    
        @Bean
        DataSource dataSource() {
            HikariConfig config = new HikariConfig();
            HikariDataSource ds;
    
            config.setDriverClassName("com.mysql.cj.jdbc.Driver");
            config.setJdbcUrl("jdbc:mysql://localhost:3306/qadb");
            config.setUsername("admin");
            config.setPassword("pass");
    
            return new HikariDataSource(config);
        }
    
        @Bean
        public TransactionAwareDataSourceProxy transactionAwareDataSource() {
            return new TransactionAwareDataSourceProxy(dataSource());
        }
    
        @Bean
        public DataSourceTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    
        @Bean
        public DataSourceConnectionProvider connectionProvider() {
            return new DataSourceConnectionProvider(transactionAwareDataSource());
        }
    
        @Bean
        public ExceptionTranslator exceptionTransformer() {
            return new ExceptionTranslator();
        }
    
        @Bean
        public DefaultDSLContext dsl() {
            return new DefaultDSLContext(configuration());
        }
    
        @Bean
        public DefaultConfiguration configuration() {
            DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
            jooqConfiguration.set(connectionProvider());
            jooqConfiguration.set(new DefaultExecuteListenerProvider(exceptionTransformer()));
            SQLDialect dialect = SQLDialect.valueOf("MYSQL");
            jooqConfiguration.set(dialect);
            return jooqConfiguration;
        }
    }

Advertisement

Answer

Spring Manual chapter 10.5.6:

Method visibility and @Transactional

When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

Advertisement