在我们的应用程序中,我们同时使用mysql服务器和redis数据库。我们将redis用作数据库,而不仅仅是缓存。我们在一个服务方法中使用这两种方法,我想让@transactional方法让spring管理我的事务。因此,如果在事务方法的中间抛出runtimeexception,那么redis和mysql上的所有工作都将回滚。我遵循了spring文档,并将@springbootapplication类配置为:
@SpringBootApplication
@EnableTransactionManagement
public 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);
}
}
这是我的服务方法:
@Service
@RequiredArgsConstructor
@Slf4j
public class FooService {
private final StringRedisTemplate redisTemplate;
private final FooRepository fooRepository;
@Transactional
public void bar() {
Foo foo = Foo.builder()
.id(1001)
.name("fooName")
.email("foo@mail.com")
.build();
fooRepository.save(foo);
ValueOperations<String, String> values = redisTemplate.opsForValue();
values.set("foo-mail", foo.getEmail());
}
但是调用testservice的测试方法后,mysql数据库中没有用户,我想是因为没有激活的事务,这个问题有没有解决的办法?我应该用Spring吗 ChainedTransactionManager
上课,然后怎么办?或者我只能通过 MULTI
?
1条答案
按热度按时间r8uurelv1#
在玩过之后
FooService
我发现用@Transactional
在一个服务方法中,专门从redis中读取一个值(我认为大多数服务方法应该从db中读取一些值)在某种程度上是无用的,因为任何读取操作都会产生一个空值,这是因为redis将事务的所有操作排队,并在最后执行它们。总结一下,我认为MULTI
以及EXEC
操作更可取,因为它提供了在redis中使用数据的更多控制。毕竟,任何使用redis事务的建议都是值得赞赏的。