0

Given the following scenario: I have an app running with Spring Boot @SpringBootApplication and setup with Spring Data JPA datasource in application.properties:

spring.datasource.url=jdbc:mysql://foo.bar.com:12345
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

and no additional java/xml configs.

I have a couple of services:

@Service
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    ProjectRepository projectRepository;

    @Override
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public Project save(Project project) {
        // there might be some additional logic here, besides the action on repository
        return projectRepository.save(project);
    }
}

and repositories:

@Repository
public interface ProjectRepository extends CrudRepository<Project, Long> {}

As it's in the code above, I found myself in need of, let's say, SERIALIZABLE level of isolation due to the app being scaled up horizontally and occasionally saving conflicting data to DB (simply @Transactional was no enough). Now, when trying I try to perform projectService.save(project) action I get an exception:

"exception": "org.springframework.transaction.InvalidIsolationLevelException",
"message": "JtaTransactionManager does not support custom isolation levels by default - switch 'allowCustomIsolationLevels' to 'true'",

Is it possible to enable those custom isolation levels with a java config?

buræquete
  • 14,226
  • 4
  • 44
  • 89
Nordar
  • 187
  • 3
  • 14

2 Answers2

0

You can enable allowCustomIsolationLevels by setting below in TransactionManager

transactionManager.setAllowCustomIsolationLevels(true);
buræquete
  • 14,226
  • 4
  • 44
  • 89
shankarsh15
  • 1,947
  • 1
  • 11
  • 16
  • My question was refering more to the fact that I do not know how to access `tramsactionManager` to be able to set that value. Can it be done somehow with `@EnableTransactionManagement`? – Nordar May 16 '16 at 05:15
  • 1
    You will be defining a transactionManager in applicationcontext.xml or some other xml file. Please set in the bean definition of transactionManager. – shankarsh15 May 16 '16 at 05:18
  • the case is I do not use xml-based spring configuration. Is it possible to be done with java config? – Nordar May 16 '16 at 05:20
  • Yes . http://docs.spring.io/spring/docs/4.2.3.RELEASE/javadoc-api/org/springframework/transaction/jta/JtaTransactionManager.html – shankarsh15 May 16 '16 at 05:27
  • 1
    http://stackoverflow.com/questions/34072965/spring-java-config-with-jta-transaction – shankarsh15 May 16 '16 at 05:33
  • I tried to do: `@Configuration public class TransactionConfig { @Bean(name = "transactionManager") public PlatformTransactionManager txManager(JtaTransactionManager jtaTransactionManager) { jtaTransactionManager.setAllowCustomIsolationLevels(true); return jtaTransactionManager; } }` but it fails to run. Is ther something that I'm missing? – Nordar May 16 '16 at 07:25
  • 1
    @Bean public PlatformTransactionManager platformTransactionManager() { return new JtaTransactionManager(); } – shankarsh15 May 16 '16 at 07:37
  • I did as you advised. Now when doing any action I'm getting `Error while committing the transaction ... Caused by: org.hibernate.TransactionException: commit failed ... Caused by: org.hibernate.TransactionException: unable to commit against JDBC connection ... Caused by: java.sql.SQLException: You cannot commit with autocommit set!` while having `spring.datasource.auto-commit=false`. I found out [link](http://stackoverflow.com/questions/26637847/spring4-hibernate4-jta-write-operations-fail) that hibernate might not be aware of WildFly JTA active transcation manager. Can that be right? – Nordar May 16 '16 at 08:20
0

my stack: Java 17, Spring Boot 3.0.6, Hibernate 6.2.5.Final, WildFly 28.0.1

Worked for me:

@Configuration
public class TransactionConfiguration {

    @Autowired
    public TransactionConfiguration(PlatformTransactionManager transactionManager) {
        JtaTransactionManager jta = (JtaTransactionManager) transactionManager;
        jta.setAllowCustomIsolationLevels(true);
    }
}
Vasily
  • 3
  • 2