redis事务学习

redis事务的介绍

redis事务的本质:一组命令的集合。redis单条命令保证原子性,但是事务不保证原子性

​ 一个事务中所有的命令都会被序列化,在事务执行过程中,会按照顺序执行,但是redis事务是没有隔离级别的概念的。所以redis的事务具有以下特性:一次性,顺序性,排他性。

​ redis事务的执行过程:

  1. 开启事务。
  2. 命令入队。
  3. 执行事务。

如何使用事务

multi // 开启事务
// 以下操作就是命令入队
set key1 value1
set key2 value2
get key1
exec // 执行事务
multi // 开启事务
// 以下操作就是命令入队
set key1 value1
set key2 value2
get key1
DISCARD // 放弃事务,放弃后队列里的命令都不会执行

事务的注意事项

  1. 当事务执行时,发生了编译型异常(代码有问题),事务汇总的所有命令都不会被执行。

    multi // 开启事务
    testredis key1 value1 //这里的testredis命令根本不存在,所以编译时就会报错,导致编译型异常
    set key2 value2 //因为上面的编译型异常,下面的正常的命令都不会执行
    get key1
    exec // 执行事务
    
  2. 运行时异常,如果编译通过了,但是事务队列中存在逻辑上的错误导致出错,除报错的命令,其他的命令都会正常执行下去。

    multi // 开启事务
    get key1 //这里的key1事先根本没有设置,就会报错,导致运行型异常
    set key2 value2 //因为上面是运行型异常,下面的正常命令都还是会执行,也是redis事务不保证原子性的体现
    get key2
    exec // 执行事务
    
  3. redis是没有事务回滚的。

redis实现乐观锁

悲观锁:很悲观,认为什么时候都会出现问题,所以无论做什么都会直接加锁。

乐观锁:很乐观,认为什么时候都不会出问题,所有不会直接加锁。而是需要操作的时候会先去获取一次值,更新数据的时候去判断一下,之前获取到的值和该数据现在的值是否一致,如果一致表示中间没有被修改过,这时再去更新。

  1. 正常情况下
set balance 10000 // 初始化余额
set consume 0 //初始化消费金额
watch balance //开启对balance的监视
multi //开启事务
decrby balace 100 // 余额减100
incrby consume 100// 消费的金额增加100
exec //提交事务
  1. 非正常情况
set balance 10000
set consume 0
watch balance
multi
decrby balace 100
incrby consume 100
exec //前面的操作是一模一样的,但是这里假如在使用exec提交事务之前,有人执行了下面的命令对数据进行了修改,这里监视到balance被修改过,那么整个事务执行会失败
incrby balance 100
  1. 取消监视
unwatch//比如你监视错了对象,取消监视,然后再重新写一次
watch balance
multi
....
exec

和关系型数据库对比

redis作为非关系型数据库,和关系型数据库还是有着许多区别,接下来就和关系型数据库里常用的mysql进行对比,并分析出他们之间对事务的不同解释。

Mysql

  1. mysql中的事务有4大特性:原子性、一致性、隔离性、持久性。

    • 原子性 (Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么均不执行。
    • 一致性 (Consistency):几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致。
    • 隔离性 (Isolation):事务的执行不受其他事务的干扰,当数据库被多个客户端并发访问时,隔离它们的操作,防止出现:脏读、幻读、不可重复读。
    • 持久性 (Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失。
  2. 针对脏读(一个事务读取到另一个事务未提交的数据),不可重复读一个事务读取到另一个事务已经提交的数据),幻读(一个事务多次查询整表数据,由于其他事务新增(删除)记录造成多次查询的记录条数不同(一个事务读取到另一个事务已经提交的数据)),提出四大隔离级别。

    • read uncommitted——不作任何隔离,具有脏读、不可重复读、幻读问题
    • read committed——可防止脏读,不能防止不可重复读和幻读问题
    • repeatable read——可以防止脏读、不可重复读,不能防止幻读问题(mysql默认是这个隔离级别
    • serializable——数据库运行在串行化,上述问题都可以防止,只是性能非常低

Redis

  1. 不保证原子性:redis同一个事务中如果发生了运行时异常(编译时异常会执行失败),其后的命令仍然会被执行。
  2. 没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行。
  3. 顺序性和排他性:事务中所有的命令都会被序列化,是先入队,再执行的操作。所以都是按照队列里的顺序挨个执行的,执行的过程中,不会被其他客户端发送来的命令请求所打断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

佛祖保佑永不宕机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值