假设以下场景: 我有一个使用 Spring Boot
@SpringBootApplication
运行的应用程序,并在 application.properties
中使用 Spring Data JPA 数据源进行设置:
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
并且没有额外的 java/xml 配置。
我有几项服务:
@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);
}
}
和存储库:
@Repository
public interface ProjectRepository extends CrudRepository<Project, Long> {}
正如上面的代码所示,我发现自己需要
SERIALIZABLE
级别的隔离,因为应用程序水平扩展并且偶尔将冲突的数据保存到数据库(仅仅 @Transactional
是不够的)。现在,当我尝试执行 projectService.save(project)
操作时,出现异常:
"exception": "org.springframework.transaction.InvalidIsolationLevelException",
"message": "JtaTransactionManager does not support custom isolation levels by default - switch 'allowCustomIsolationLevels' to 'true'",
是否可以使用 java 配置启用这些自定义隔离级别?
您可以通过在
allowCustomIsolationLevels
中进行以下设置来启用
TransactionManager
transactionManager.setAllowCustomIsolationLevels(true);
我的堆栈:Java 17、Spring Boot 3.0.6、Hibernate 6.2.5.Final、WildFly 28.0.1
为我工作:
@Configuration
public class TransactionConfiguration {
@Autowired
public TransactionConfiguration(PlatformTransactionManager transactionManager) {
JtaTransactionManager jta = (JtaTransactionManager) transactionManager;
jta.setAllowCustomIsolationLevels(true);
}
}