概述
Redis中的事务是一组命令的集合。一个事务中的命令要么都执行,要么都不执行。Redis命令能保证一个事务内的命令依次执行而不被其他命令插入。Redis事务没有提供类似关系型数据库的回滚功能。
MULTI:开启事务,告诉Redis接下来输入的多条命令不立马执行,而是先存起来;
EXEC:提交事务,将一组命令提交一起挨个执行。
错误处理
语法错误
语法错误指的是命令不存在或命令参数不对。一组命令中,只要有一个语法错误,执行EXEC后Redis会直接返回错误,连语法正确的也不会执行。(PS:仅针对Redis2.6.5及以后的版本来说)
运行错误
运行错误指在命令执行时出现的错误,比如使用散列类型的命令操作集合类型的键,这种错误在实际执行之前Redis是无法发现的,所以在事务里这样的命令会被Redis接受并执行的。如果事务里的一条命令出现了运行错误,事务里其他命令依然会继续执行。
WATCH命令
介绍
WATCH命令可以监控一个键,当该键对应的值被修改后,可以阻止之后对该键值进行修改的一个事务的执行。
如图,在WATCH “key”这个键后,又SET了该键的值,所以后面的事务没有执行成功。
执行EXEC命令会取消对所有键的WATCH监控,如果不想执行事务中的命令,也可以用UNWATCH来取消对所有键的监控。
应用场景
在什么情景下需要使用WATCH?比如说,你先要GET某个键的值,对值进行一些操作之后,再SET该键的新值,但这样可能会出现竞态条件。虽然Redis事务可以执行一组命令并且也是原子的,但是在Redis事务中你没法获取上一条命令的返回值,因为所有命令都是执行完EXEC命令之后一起依次执行的,返回值是一起返回的。所以我们可以用WATCH+事务来完成上述GET和SET操作,假如在执行事务之前该键值被修改(也就是出现了竞态条件),事务会执行失败,这时你可以选择重试。
Redis事务的JAVA demo(使用RedisTemplate)
Object result = stringRedisTemplate.execute(new SessionCallback<Object>() {
@Override
public List<Object> execute(RedisOperations operations) throws DataAccessException {
operations.multi();
//一些Redis命令
return operations.exec();
}
});
参考资料
- 《Redis入门指南》第2版,李子骅