11. SDR 事务

我们知道Redis 是支持弱事务的, Redis 中的事务只能保证命令在同一个连接中执行,当发生异常后并不会进行事务回滚. SDR 对这种弱事务也提供了支持。 除了支持redis-cli 客户端的multi, exec, discard 命令之外, SDR 还支持使用声明式注解@Transaction 注解类强制开启事务, 但笔者并未使用过,如果有兴趣,可以自行尝试。

1. SDR 事务

1.1 SDR 事务特点

  • 事务中所有命令, 在同一连接中执行
  • 事务中的所有命令,在执行exec方法时,才开始依次执行
  • 事务中所有命令都会执行,纵使中间有命令报错,也不会终止后面的命令执行
  • 事务中发生异常时,已执行的命令不会发生回滚。

1.2 相关API

方法签名方法描述
void multi()开启事务
List exec()执行事务, 返回每条命令的返回结果
void discard()丢弃事务

1.3 @Transaction 强制开启事务

SDR 中默认RedisTemplate是关闭事务,可以配置自定义RedisTemplate时,设置强制开启事务 setEnableTransactionSupport(true). 此方法会强制当前RedisTemplate 绑定的RedisConnection在当前线程中强制开启事务, 当事务结束时,若没有异常则自动触发exec方法提交事务,否则自动触发discard方法丢弃事务.

1.4 事务和pipeline 的区别

虽然事务和pipeline看起来很相似,都可以批量执行命令,但是还是有本质性的不同的。

  • 相同点:
    1. pipeline 和 事务都是在同一连接中执行的, 减少了多次TCP连接创建销毁的实际,提高了性能
    2. pipeline 和 事务当执行命令过程出现异常时均不会终止后面的命令运行
  • 不同点:事务是当执行exec方法时, 统一开始执行命令; 当执行ops的相关命令时,并非真正的执行. 而pipeline则时,执行ops 命令时就真正开始执行命令.

2. API 测试

2.1 提交事务exec

  • 执行测试用例前,先清空redis数据库或删除redis中key为 A,B,C 的key-value
  • 从控制台输出可以看出, 虽然执行第二天命令失败了,但是并没有抛出异常,也没有终止剩余命令执行
@Test
public void test_exec(){

    List<Object> txResults =  stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
        @Override
        public List<Object> execute(RedisOperations operations) throws DataAccessException {
            // 开启事务
            operations.multi();

            ValueOperations ops = operations.opsForValue();
            ops.set("A", "aaaa");
            ops.setIfPresent("B","aaa");
            ops.set("C", "cccc");

            // 执行事务
            return operations.exec();
        }
    });

    // 遍历返回结果
    for (Object txResult : txResults) {
        System.out.println(txResult);
    }
    
    /* 控制台输出
        true
        false
        true
    */
}

2.2 取消事务discard

  • discard 会取消事务中的命令,并丢弃
  • 测试之后,发现redis中并没有A, B, C三个key, 这说明虽然调用了ops.set方法, 但是命令并没有执行.
@Test
public void test_discard(){

    List<Object> txResults =  stringRedisTemplate.execute(new SessionCallback<List<Object>>() {
        @Override
        public List<Object> execute(RedisOperations operations) throws DataAccessException {
            // 开启事务
            operations.multi();

            ValueOperations ops = operations.opsForValue();
            ops.set("A", "aaaa");
            ops.set("B","aaa");
            ops.set("C", "cccc");

            // 取消事务
            operations.discard();

            return null;
        }
    });
    System.out.println("txResults:" + txResults);
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值