redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令能够连续的执行,而中间不会插入其余client的命令。 因为redis是单线程来处理全部client的请求的因此作到这点是很容易的。通常状况下redis在接受到一个client发来的命令后会当即处理并 返回处理结果,可是当一个client在一个链接中发出multi命令有,这个链接会进入一个事务上下文,该链接后续的命令并非当即执行,而是先放到一 个队列中。当今后链接受到exec命令后,redis会顺序的执行队列中的全部命令。并将全部命令的运行结果打包到一块儿返回给client,而后结束事务上下文。redis
数据ACID特性知足了几条?服务器
为了保持简单,redis事务保证了其中的一致性和隔离性;async
不知足原子性和持久性;spa
redis事务在执行的中途遇到错误,不会回滚全部的命令,而是继续执行后续命令;(违反原子性)线程
事务能够理解为一个打包的批量执行脚本,但批量指令并不是原子化的操做;队列
中间某条指令的失败不会致使前面已作指令的回滚,也不会形成后续的指令不作;进程
示例:事务
127.0.0.1:6379> set b 11 # 设置 b 对应的 value 为字符串类型内存
OK字符串
127.0.0.1:6379> multi # 开启事物
OK
127.0.0.1:6379> sadd a aa aaa # 添加一个 set key 为 a
QUEUED
127.0.0.1:6379> sadd b bb bbb # 添加一个 set key 为 b,此时由于 b 对应的 key 已被占用,并且对应的数据类型为 string,因此这里会失败
QUEUED
127.0.0.1:6379> sadd c cc ccc # 添加一个 set key 为 c
QUEUED
127.0.0.1:6379> exec # 提交事务,两个成功一个失败,并无所有回滚
1) (integer) 2
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) (integer) 2
127.0.0.1:6379> SMEMBERS a
1) "aa"
2) "aaa"
事务不过是用队列包裹起了一组 Redis 命令,并无提供任何额外的持久性功能,因此事务的持久性由 Redis 所使用的持久化模式决定:
在单纯的内存模式下,事务确定是不持久的。
在 RDB 模式下,服务器可能在事务执行以后、RDB 文件更新以前的这段时间失败,因此 RDB 模式下的 Redis 事务也是不持久的。
在 AOF 的“老是 SYNC ”模式下,事务的每条命令在执行成功以后,都会当即调用 fsync 或 fdatasync 将事务数据写入到 AOF 文件。可是,这种保存是由后台线程进行的,主线程不会阻塞直到保存成功,因此从命令执行成功到数据保存到硬盘之间,仍是有一段很是小的间隔,因此这种模式下的事务也是不持久的。
其余 AOF 模式也和“老是 SYNC ”模式相似,因此它们都是不持久的。
redis事务在执行的过程当中,不会处理其它命令,而是等全部命令都执行完后,再处理其它命令(知足隔离性)
redis事务在执行过程当中发生错误或进程被终结,都能保证数据的一致性;
事务回滚
另外一个 client 修改 watchkey 的值,致使主窗口的事务提交失败