Redis对于事务的支持目前很简单。只能保证client发起的事务中的命令可以连续执行,而不会插入其他client命令,当一个client在一个连接中发出multi命令时表示连接进入了事务上下文,该连接后续的命令不会立即执行,而是先放一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。
1. 事务处理
执行事务
一个事务从开始到执行会经历以下三个阶段:开始事务,命令入队,执行事务。
它先以 MULTI 开始一个事务,然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务,一并执行事务中的所有命令:
Multi开启事务上下文,exec是执行命令,而set是将多个命令进行队列中去。
我们会发现设置过程中键相同的值将会覆盖之前的值。
取消事务
Dicard是取消命令块内的设置,也就是取消事务。
此时设置事务并且执行discard,会发现值还是之前的100。可以发现2个set age 命令都没有执行。Discard命令其实就是清空事务的命令队列并退出事务上下文,也就是我们说的事务回滚。
事务中锁的机制
当事务中的某一个队列中某一个命令出现错误的时候不会出现回滚。
此时发现年龄age执行,但是name没有执行。
针对这种现象提出了乐冠锁的概念。那么什么是乐冠锁呢?
乐观锁:大多数是基于版本控制的,也就是为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表添加一个“version”字段来实现数据读取,将此版本号一同读出,之后更新,此时版本号加1,发生了变化。此时,将提交数据的版本号与数据库表对应记录的当前版本号进行对比,如果提交的版本号大于数据库当前的版本号,则予以更新,否则认为是过期数据。
我们开启两个客户端窗口:
我们先watch,此时再修改age的值,此时发现执行时失败,这就是watch的作用。
小结:watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。当然是监视多个key值的,注意,watch的key是对整个连接有效的,事务也是一样的,连接端口,事务和监视将会自动清除,exec,discard,以及unwatch均会自动清除连接中的监视。
2. 持久化
Redis不同于memcached之处是不仅仅是可以将数据缓存在内存中,同样是可以将数据持久化到数据库的。Redis是一个支持持久化的内存数据库,也就是说redis需要经常讲内存个的数据同步到硬盘来保证数据的持久化(防止关闭或者宕机的出现使得数据丢失)。
通常存在两种方式:snapshotting(快照)也是默认方式;append-onlyfile(缩写为aof)的方式。
snapshotting(快照)
快照是默认的持久化方式,这种方式是将内存中数据以快照的方式 写入默认的文件名为dump.rdb文件中。可以通过配置二进制文件中设置自动做持久化的快照方式,可以配置redis在n秒内如果超过m个key就自动做快照。
在window命令下使用dir/w查看某个文件夹下所有的文件名称。
此时发现存在一个dump文件,注:二进制文件是无法查看的
配置文件中配置:
表示900内更新一个键值就持久化,第二是300秒内更新10个键值就持久化,第三个是60秒内更新10000个就持久化。
append-only file
由于快照方式是在一定时间间隔内更新的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改。
Aof比快照方式有更好的持久化性,是由于在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。
操作过程
当然由于os会在内核中缓存write做的修改,所有可能不是立即写到磁盘上,这样aof方式的持久化也还是由可能会丢失部分修改的。
我们可以通过配置文件告诉redis,我们想要通过fsync函数强制os写入磁盘的时机。
我们看一下配置文件,我们知道默认情况下使用的是第一种方式,所以配置文件中的aof为no.
我们可以将no改为yes,就会采用appendonly方式了。
此外还有:
Appendonly yes:表示启动aof持久化方式。
Appendfsyncalways:收到写命令就立即写入磁盘,最慢,但是保证完全的持久化。
Appendfsynceverysec:每秒写入磁盘一次,在性能和持久化方面做了很好的折中。
Appendfsync no:完全依赖os,性能最好,持久化没保证。
配置文件配置
此时需要关闭服务重新启动,此时查看redis目录文件,使用命令dir/w:
此时出现了我们想要的效果。
3. 小结
无论哪种方式都是为了使得我们的数据更加的安全,动手试试吧~