Redis的高级功能-----事务
概述
事务:事务允许用户将多个命令打包成一个操作来执行,确保这些命令要么全部成功,要么全部失败,从而保证数据的一致性和原子性
事务
事务的优点
原子性:Redis事务可以保证多个命令的原子性执行,即要么全部执行,要么全部不执行。
性能:Redis事务可以将多个命令打包成一个批量操作,从而减少网络通信的开销,提高性能。
一致性:Redis事务可以保证多个命令的一致性,即在执行事务期间,其他客户端不会对这些命令进行修改。
实现方式
MULTI:开始一个事务。
EXEC:执行事务中的所有命令。
DISCARD:取消事务。
WATCH:监视一个或多个键,如果在事务执行期间这些键被修改,事务将被取消。
示例:
/**
* 事务操作
* @param isOpenError 是否开启异常
*/
public void transactionalMethod(boolean isOpenError) {
redisTemplate.execute(new SessionCallback<List<Object>>() {
@Override
public List<Object> execute(RedisOperations operations) {
operations.multi(); // 开启事务
ValueOperations<String, String> valueOps = operations.opsForValue();
valueOps.set("key1", "value1");
if(isOpenError){
int i = 1 / 0;
}
valueOps.set("key2", "value2");
List exec = operations.exec();//提交事务
return exec;
}
});
}
注意事项
Redis事务不支持回滚操作。
如果在执行事务期间,键被其他客户端修改,那么事务将被取消。
Redis事务不支持嵌套事务。
Redis事务中的命令不能使用事务外的数据。
Redis事务中的命令不支持乐观锁。
解答
Redis 的单线程模型
Redis 的单线程是指其网络事件处理和命令执行是在一个线程中完成的。这意味着,Redis 在处理某一个客户端请求时,其他请求会被挂起,按顺序处理。这确保了单个命令的原子性。
Redis 事务的行为
Redis 的事务由以下几个阶段组成:
- 开始事务 (
MULTI):将后续命令放入事务队列,但不会立即执行。 - 命令入队:每个命令会按顺序被加入事务队列。
- 执行事务 (
EXEC):Redis 按照事务队列中的顺序一次性执行所有命令。
重要的一点是,Redis 的事务不支持回滚,也没有锁机制。事务内的命令不会在入队时立即检查键的状态,而是在事务执行 (EXEC) 时才实际执行。
为什么其他客户端可以影响事务?
在事务命令入队和实际执行 (EXEC) 之间,事务并未锁住这些键。其他客户端可以同时发送命令并修改键的值。
例如:
- 客户端 A 发送:
MULTI GET key1 SET key1 value1 - 此时事务队列中仅记录了
GET key1和SET key1 value1。 - 在客户端 A 发送
EXEC之前,客户端 B 修改了key1的值。 - 当
EXEC执行时,事务仍会执行GET key1和SET key1 value1,此时读取和写入的值可能与预期不同。
乐观锁的作用
为了解决这一问题,Redis 提供了乐观锁机制(基于 WATCH)。WATCH 监视一个或多个键,如果在事务执行前这些键被修改,事务会自动取消。流程如下:
- 客户端 A 发送:
WATCH key1 MULTI GET key1 SET key1 value1 - 如果
key1在EXEC前被其他客户端修改,事务会中止,EXEC返回空值。

浙公网安备 33010602011771号