1. springboot开启redis事务


@Configuration
public class RedisConfig {

    @Bean("redisTX")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setEnableTransactionSupport(true);
        return redisTemplate;
	}
}

注意使用redis事务不一定保证原子性,需要使用@Transactional注解可以和mysql保证事务一致性,但是不推荐
可以在redis配置里初始化两个bean, 一个开启事务,一个不开启

同时redis原生事务在cluster集群模式下无法生效(MULTI、EXEC、WATCH、DISCARD、UNWATCH)

  • MULTI 开启事务

  • WATCH 待监视Keys

  • UNWATCH 移除待监视的Keys

  • EXEC 提交执行事务

  • DISCARD 放弃执行事务

在 Redis 中,MULTI 命令开始一个事务块,然后通过 EXEC 命令执行事务。事务中的命令并不会立即执行,而是被放入一个队列中,直到 EXEC 命令被调用才会执行队列中的命令。
Redis 的事务在执行过程中如果发生了错误,比如语法错误或者事务中某个命令执行失败,它并不会回滚已经执行的命令,而是会继续执行后面的命令。这就导致了事务并不是原子性的,因为事务中的命令可能部分执行成功,部分执行失败。
如果需要原子性操作,可以考虑使用 Redis 的 WATCH 命令配合 MULTI/EXEC 来实现乐观锁机制,或者使用 Redis 的 Lua 脚本来确保一系列命令的原子性执行。

如果要解决以上场景问题,开启 enableTransactionSupport 自然是能解决问题,但是并非最佳手段,如 redis 的缓存异步提交,甚至监听 binlog 再提交,都是不错的选择。如果觉得这样做成本略大,当然也可以自行封装 RedisTemplate,将所有 JDBC 事务中的 Redis 命令收集到 Queue 中,等到事务提交后再执行。

参考文章:

1.Redis事务
2. 一次 Redis 事务使用不当引发的生产事故

文章作者:
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
喜欢就支持一下吧