标签:安全 用户 lag 状态 always 自己 安全性 检查 flags
事务
事务原理是,在事务状态下,客户端输入的命令服务器不会立即执行,而是将所有的命令按输入的顺序放入到一个队列当中,当用户执行了commit操作,服务器再按顺序执行所有的命令,并一次性将结果返回。
Redis 的事务开启命令为multi,事务状态下输入的命令不会立即执行,返回一个quene,二在客户端执行了exec命令后,就立即执行队列中的命令。
事务开启multi
multi命令将执行命令的客户端状态改为事务状态,通过在客户端的flags属性打开redis_multi标识来完成。
事务队列
每个redis的客户端都有自己的事务状态,保存在mstate(multistate结构)属性里面,multistate包括一个事务队列和一个已入队的命令计数器,事务队列是一个multicmd类型的数组,数组的每个元素都保存了指向命令实现函数的指针,命令的参数,参数数量。事务队列采用fifo方式保存入对的命令。
执行事务
客户端执行exec命令后,服务端会立即执行,遍历并执行事务队列中的所有命令。最后将所有的结果返回给客户端。
watch命令的实现
watch是一个乐观锁,可以监视任意数量的键,在事务期间如果修改了任何一个被监视的键,服务器将拒绝执行该事务,并向客户端返回代表事务执行失败的空回复。
没个数据库中都有一个watch_keys的字典,键为被监视的键,值为一个链表,链表的每个节点都是监视该键的客户端。
通过命令watch key1 key2 可以将键与客户端关联起来。
监视机制的触发
所有在对键进行修改的命令执行后都会调用这个multi.c/touchwatchkey函数对watch_keys进行检查,如果被监视的键被修改的化,那么函数会将被监视键的客户端的redis_dirty_cas标识打开,表示该客户端的事务安全性被破坏。
判断事务是否安全
事务的acid性质
原子性—事务当中的操作要么全部执行,要么都不执行。
一致性—事务执行之前数据库是一致的,执行后也应该是一致的。
隔离性—每个事务之间是完全独立的,并发的执行每个事务。
持久性—每个事务执行完毕后,结果被永久的保存,例如保存在硬盘当中。
因为redis的事务机制是将命令简单的包裹在队列中,并没有提高持久化的操作,所以在没有持久化的模式下,redis不具有持久性,即事务的结果会丢失。
在rdb模式下,服务器只会在特定的条件下才会执行bgsave命令,并且异步的bgsave命令并不会第一时间将事务的数据保存到硬盘,所以也不具有持久化。
在aof模式下,并且appendfsync选项为always时,程序会在执行命令后调用sync函数,将数据真正的保存到硬盘里,所以具有持久化。
在aof模式下,并且appendfsync选项为everysec时,程序会每秒同步一次命令数据到硬盘,因为停机或其他的故障可能就发生在那一秒之内,可能造成数据的丢失,所以不具有持久性。
入队错误—在事务状态下,入对如果输入了不存在的命令,服务器会拒绝执行该事务。
执行错误—执行错误时都是在执行的时候才会发现的错误,服务器遇到该错误,不会停止而是继续执行。并且已执行的命令不会被错误影响。
标签:安全 用户 lag 状态 always 自己 安全性 检查 flags
原文地址:https://www.cnblogs.com/laoyu-love-life/p/14615914.html