一、简介
Redis事务可以一次执行多个命令,可以理解为批量执行脚本。值得注意的是Redis事务的执行不是原子性的,比如中间某条指令执行失败,既不会导致前面已执行指令回滚,也不会导致后面指令不做。
二、事务命令
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。 |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
三、执行步骤
- multi开始事务
- 指令入队列
- exec执行事务
代码片段如下:
Jedis jedis = jedisPools.get(index);
//监视key
jedis.watch(watchKey);
//开始事务
Transaction transaction = jedis.multi();
//批量的Redis指令
infoOperator.updateField(key, map);
infoOperator.expireKey(key);
//执行事务
List<Object> response = transaction.exec();
//取消对key的监视
jedis.unwatch(jedis);
//关闭jedis的连接
this.closeJedis(jedis, userName);
四、乐观锁控制事务
乐观锁的核心:如果提交数据的版本号大于数据库当前版本号,则提交成功。
Redis事务原理:redis中用watch监视key,如果key在提交前被修改(数据库当前版本号已发生变化),则提交不成功。
如上图所示,整个事务执行失败,exec后返回(nil)。原因如下:
当session1还没来得及对age进行修改,session2已经将age的值设为30,session1再执行的时候就会失败,因为session1对age加了乐观锁。