Redis事务可以一次执行多个命令,事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。 事务特性ACID原子性、一致性、隔离性和持久性中,Redis单条命令满足原子性,但Redis事务不满足原子性!运行异常那有举例。 Redis事务本质是一组命令的集合,把命令序列化后按顺序执行,此外Redis没有分隔离级别,故没有幻读脏读等。 Redis事务过程:
命令 | 作用 | 示例 |
---|---|---|
multi | 标记一个事务块的开始。 随后的指令将在执行EXEC时作为一个原子执行。 | |
exec | 执行事务,当使用WATCH 时,只有当被监视的键没有被修改,且允许检查设定机制时,EXEC会被执行 | |
discard | 放弃事务,已入队命令不执行。如果已使用WATCH,DISCARD将释放所有被WATCH的key。 |
编译异常即命令有错,不能通过编译,此时事务中的所有命令都不会执行。 比如:
运行异常即执行命令时错误(比如处理了错误类型的键:list命令用在string键上等),执行错误命令时抛出异常,但其他命令正常执行。即不满足原子性(一起成功一起失败) 比如:
悲观锁:认为什么时候都会出错(悲观),所以无论做什么都会加锁。 乐观锁:认为什么时候都不会出错(乐观),所以不会加锁,更新数据时判断(check-and-set检查设定机制)。
Redis提供了命令来支持乐观锁:
命令 | 作用 |
---|---|
watch key [key …] | 标记所有指定的key被监视(加锁)起来,在事务中有条件的执行(乐观锁) |
unwatch key [key …] | 取消监视,如果执行EXEC 或者DISCARD, 则不需要手动执行UNWATCH 。 |
在客户端2修改k1的值,比如从卡1取500
然后回到客户端1输入exec执行事务
返回nil,事务执行失败。
那么怎么解决呢?只要重新watch即可获取最新数据,可以先unwatch放弃监视
这样一来就能实现乐观锁了,应用于转账、秒杀等等。
原创不易,请勿转载(
本不富裕的访问量雪上加霜) 博主首页:https://blog.csdn.net/qq_45034708