In our application we are using both MySQL server and Redis databases. we use Redis as a database and not just a cache. we use both of them in a service method and I want to make the method @Transactional to let the spring manages my transactions. Hence if in the middle of an transactional method a RuntimeException is thrown all works on both Redis and MySQL are rolled back. I have followed the spring docs and configured my @SpringBootApplication class as following:
@SpringBootApplication@EnableTransactionManagementpublic class TransactionsApplication { @Autowired DataSource dataSource; public static void main(String[] args) { SpringApplication.run(TransactionsApplication.class, args); } @Bean public StringRedisTemplate redisTemplate() { StringRedisTemplate template = new StringRedisTemplate(redisConnectionFactory()); // explicitly enable transaction support template.setEnableTransactionSupport(true); return template; } @Bean public LettuceConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379)); } @Bean public PlatformTransactionManager transactionManager() throws SQLException, IOException { return new DataSourceTransactionManager(dataSource); }}
and this is my service method:
@Service@RequiredArgsConstructor@Slf4jpublic class TestService { private final StringRedisTemplate redisTemplate; private final UserRepository userRepository; @Transactional public void test() { User test = User.builder() .id(1001) .name("test") .email("test@mail.com") .build(); userRepository.save(test); Optional<User> userOpt = userRepository.findById(1001); if(userOpt.isEmpty()){ throw new RuntimeException("not-found"); } User user = userOpt.get(); user.setName("Test_2"); user.setEmail("Test_2@mail.com"); userRepository.save(user); ValueOperations<String, String> values = redisTemplate.opsForValue(); values.set("my-key", user.get().getEmail()); }
However after the test method of TestService is called there is no user in MySQL db and I think it's because there is no active transaction for it.Is there any solution for this problem? Should I use spring ChainedTransactionManager
class and then how? or I can only manage Redis transactions manually through MULTI
?