Redis事务
事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而改去执行其他客户端的命令请求,它会将事务中的所有命令都执行完毕,然后才去处理其他客户端的命令请求。
MULTI命令可以将执行该命令的客户端从非事务状态切换至事务状态
在redis开始事务状态时,所有的操作都将被放入一个队列里面。(除过multi exec watch discard)
如果遇见上述四个命令,则立即执行
1、watch命令
redis数据库使用watched_keys这个字典,来保存被监控的key以及所监控的客户端。在此字典中,key为所被监视的key,而value则为一个链表,保存着客户端的地址信息。
在redis的客户端中,REDIS_DIRTY_CAS标识用来决定是否执行事务。默认情况下,此标识为关闭状态。当客户端所监控的key被修改时,此标识被打开。此时执行事务,则会被redis所拒绝。
首先用第一个客户端给message设置值。然后没开启事务的时候,两个客户端都可以修改message的值。
当第二个客户端开始事务的时候,用客户端1修改message的值,然后在客户端2里面对message进行一系列操作,最后提交事务,这时候,redis返回nil拒绝执行此事务
2、redis的事务特性
传统的事务都具有一下四点性质: 同样,redis也具有一下特性。
原子性:统一事务内的所有命令要么一起执行,要么都不执行。
一致性:执行事务前后的数据库状态应该保持一致。
在redis中,在命令入队时,可能出现一个不存在的命令。那么在事务执行过程中,redis将拒绝执行此事务!
在以上的示例中,首先将message设置为string键,然后在用列表键命令操作message,最后执行事务。可以看到,最终返回的message的值仍未string,而不是列表类型。
在redis使用过程中,如果出现服务器停机等故障,redis也会根据rdb或者aof等方式来进行数据恢复,从而使数据库达到一致性!
隔离性:在事务执行过程中,一个事务不会对其他事务的执行产生影响。因为redis是单进程、单线程来处理,所以在一个事务没执行完,不会切换去执行其他事务。
持久性:在事务执行完之后,事务所得的结果被永久保存在磁盘中(也可以是其他介质)。
由于redis的事务仅仅是简单的一组命令,所以redis只在一定情况下具有持久性
没开启持久化的服务器的事务不具有持久性
RDB模式下的redis服务器不具有持久性
AOF模式下:appendfsync值为aways具有持久性 everysec不具有持久性 no不具有持久性
no-appendfsync-on-rewrite的值对aof模式下的持久性也有影响。
当no-appendfsync-on-rewrite选项处于打开状态时,在执行BGSAVE命令或者BGREWRITEAOF命令期间,服务器会暂时停止对AOF文件进行同步,从而尽可能地减少I/O阻塞。此时,会有一部分数据没写入aof文件而导致其不存在持久性。所以此选项默认是关闭的。
所以,要是redis具有持久性,可以在每条事务后面加save或者bgsave。不过这样一来,由于频繁的进行数据的持久化会导致性能急剧下降。所以不建议这么做