Redis事务
多个客户端 对相同数据 执行写入时,有可能出现 数据安全的问题;
三个重点:
多个客户端
对相同数据
写入操作
/*******************************************************************************************************************************/
我们知道Redis是单线程,one by one 执行 命令(Redis6以后是支持多线程的)
这种数据安全问题 是如何产生的
首先 Redis可以同时连接多个客户端,重点是同时连接,通过Redis的连接池技术;
我Redis同时连接多个客户端,可是多个客户端发过来的命令,我是一条一条执行的,一条条的命令保证原子性;
比如 incr 命令 getset 命令
但是不同客户端的多个命令操作相同key时 会相互干扰
比如 num=12
A客户端 先检查num (如果num>=10 则 更改 num为100,如果num<10 则更改num 为0);
这个时候A看到num是12 下一步A会把 num 取过来执行操作;
这个时候,B把num改成了9;
//一条条命令保证原子性,可是多个客户端可能在任何时候发命令过来
这个时候A把num取出来 执行操作的时候就会抱错(num在A的两个命令之间发了一个命令过来把num改成9了)
所以Redis提供了事务机制 应对这样的问题
/******************************************************************************************************************************/
与MySQL 中的
BEGING;
COMMIT; 或者 ROLLBACK;
命令来执行事务类似
Redis
通过
multi 命令开启事务
exec 命令最终执行事务中的全部命令 或者 返回提示信息,事务中的命令都不予执行;
Redis可以通过在multi命令之前
执行watch命令监控某个 或多个 key
形成一个乐观锁的机制 如果 这款key没有被改写,则 exec 执行成功
如果 exec
在 一条一条执行命令(有可能来自其他客户端的命令,redis是一条一条执行命令的) 的 过程时间中,
没其他客户端的命令 改写 了监控的key 则执行成功
否则exec执行失败
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
使用事务提高 性能
这个技巧 被称为 流水线 模式
原由是
Redis 服务器 会 延迟执行 已入队的 事务中的命令 ,
直到客户端发送 exec 命令;
所有客户端都采用流水线模式
也就是 客户端 会把 需要 执行的命令们 组织好 成一个事务
就是
multi
某某
某某
exec
一并发给服务器
这种一次发送多个命令,然后等待所有命令的执行结果出现的做法就是 流水线模式
这样可以减少客户端 与Redis服务器之间的连接次数,提升Redis在执行多个命令的性能;