Redis的订阅事务持久化
Posted Dream
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis的订阅事务持久化相关的知识,希望对你有一定的参考价值。
1、Redis事务概念
(1)概念
redis的事务可以一次执行多个命令,它是按顺序地串行化执行,执行的过程中不允许插入其他命令。
不支持事务回滚
(2)常用命令
- discard:取消事务,放弃执行事务块内的所有命令
- exec:执行所有事务块内的命令
- multi:标记一个事务块的开始
- unwatch:取消watch命令对所有key的监视
- watch:监视一个或多个key,如果在事务执行之前这个key被其他的命令所改动,那么事务将会被打断
(3)应用
在商品秒杀的过程中,当用户抢到了秒杀的商品后,要保证添加秒杀成功的用户的信息与用户的移除一起执行
(4)事务总结
Redis单条命令是保证原子性的,但是Redis的事务是没有原子性的。
Redis的事务执行的过程:开启(multi)、入队、执行(exec)
异常:编译时异常(代码有错误),队列中的所有命令都不会被执行。运行时异常,如果存在语法性错误,其他命令正常执行,错误命令抛出异常。
2、转账案例
(1)命令流程
127.0.0.1:6379> set account:a 100 OK 127.0.0.1:6379> set account:b 51 OK 127.0.0.1:6379> get account:a "100" 127.0.0.1:6379> set account:a 100 OK 127.0.0.1:6379> set account:b 50 OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> get account:a QUEUED 127.0.0.1:6379> get account:b QUEUED 127.0.0.1:6379> decrby account:a 10 QUEUED 127.0.0.1:6379> incrby account:b 10 QUEUED 127.0.0.1:6379> get account:a QUEUED 127.0.0.1:6379> get account:b QUEUED 127.0.0.1:6379> exec 1) "100" 2) "50" 3) (integer) 90 4) (integer) 60 5) "90" 6) "60"
现在两个账户中存入一定金额,通过命令multi开启一个事务,在执行exec命令之前,输入的其他命令都加在了一个队列里面,exec命令会执行事务快内的所有元素。
3、discard命令
(1)概念
在输入multi命令后所有的命令都会进入到一个队列中,但是没有执行。在执行exec命令之前,可以通过discard命令来放弃队列的内容。
(2)命令
127.0.0.1:6379> multi OK 127.0.0.1:6379> set hello 123 QUEUED 127.0.0.1:6379> get aa QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> exec (error) ERR EXEC without MULTI
4、redis的事务处理
(1)概念
如果执行某一个命令出现了错误,则只有报错的命令不会执行,其他命令都会执行,不会回滚
(2)redis语法错误时的事务处理
127.0.0.1:6379> set aaa nihao QUEUED 127.0.0.1:6379> get aaa QUEUED 127.0.0.1:6379> get aaa QUEUED 127.0.0.1:6379> get aaa QUEUED 127.0.0.1:6379> incr aaa QUEUED 127.0.0.1:6379> exec 1) OK 2) "nihao" 3) "nihao" 4) "nihao" 5) (error) ERR value is not an integer or out of range
错误的命令报错,但是没有错误的命令都能正常执行
(3)redis命令错误时的事务处理
127.0.0.1:6379> multi OK 127.0.0.1:6379> set aaa 123 QUEUED 127.0.0.1:6379> get aaa QUEUED 127.0.0.1:6379> qqqqq (error) ERR unknown command \'qqqqq\' 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors.
队列中的某一个命令出现错误,那么整个队列就会被取消
5、redis事务的watch
一个事务监视aaa并处理aaa:
127.0.0.1:6379> watch aaa OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set aaa 123 QUEUED 127.0.0.1:6379> get aaa QUEUED 127.0.0.1:6379> incr aaa QUEUED 127.0.0.1:6379> exec (nil)
另一个事务在上面的事务提交之前将aaa的值改变:
127.0.0.1:6379> set aaa 111 OK 127.0.0.1:6379> get aaa "111"
为了保证数据的安全,aaa并没有获得值
6、持久化
Redis的持久化:可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。存储在内存中的数据虽然高效,但是断电的时候数据会丢失;存储在硬盘上的数据速度虽然慢于内存,但是断电不会丢失。
Redis的持久化支持两种方式:
(1)RDB持久化
将数据以快照的形式存储到磁盘上(二进制文件),当再次重启服务器的时候可以直接读取磁盘上的快照,默认的文件名为:dump.rdb。
优势:
适合于数据量较大的数据库操作,这是相对于AOF方式的持久化而言的,如果数据库的操作过于复杂那么日志文件也会相当复杂,数据库的恢复过程工作量会相应增加。
快照保存的数据极快,还原数据极快
适合于灾难备份
劣势:
易丢失数据,快照是在一定的时间间隔做一次,如果redis意外down掉的话,就会丢失快照后的所有修改
小内存机器不适合使用(占用内存较多)
(2)AOF持久化
比快照方式有更好的持久性,在使用aof持久化方式的时候,redis会将每一个收到的写命令都通过write函数追加到文件中。以日志的形式记录数据库的操作,当重启服务器后读取日志文件,重建整个数据库的内容。
劣势:
持久化的文件会越来越大,例如:调用incr test命令100次,文件必须保存全部的100条命令,其中有99条是多余的。
7、乐观锁
Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断,类似于Java中的CAS算法。
以上是关于Redis的订阅事务持久化的主要内容,如果未能解决你的问题,请参考以下文章