Redis事务与watch

Redis的事务

  Redis中的事务(transaction)是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次执行这些命令。Redis保证一个事务中的所有命令要么都执行,要么都不执行。如果在发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的所有命令都不会执行。而一旦客户端发送了EXEC命令,所有的命令就都会被执行,即使此后客户端断线也没关系,因为Redis中已经记录了所有要执行的命令。

Redis事务没有隔离级别的概念
  批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。

Redis不保证原子性
  Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

Redis事务的相关命令
watch key1 key2 ...: 监视一或多个key,如果在事务执行之前,被监视的key被其他命令改动,则事务被打断 ( 类似乐观锁 )multi : 标记一个事务块的开始( queued )
exec : 执行所有事务块的命令 ( 一旦执行exec后,之前加的监控锁都会被取消掉 ) 
discard : 取消事务,放弃事务块中的所有命令
unwatch : 取消watch对所有key的监控

事务的实现从开始到结束通常会经历三个阶段:
a.事务开始阶段
在这里插入图片描述
b.命令入队列
  当事务执行时,Redis客户端有自己的事务状态,状态中含有一个事务队列以及已入队列命令的计数器,命令按照fifo的方式进入队列。事务队列是一个multiCmd的数组,每个multiCmd结构都保存了一个已入队命令的相关信息。
c.事务执行
  当处于事务状态的客户端向服务器发送exec命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将结果返回给客户端。

Watch命令

  WATCH是一个乐观锁,类似于java的juc包的CAS,它可以在exec命令执行之前,监视任意数量的数据库键并在exec命令执行时,检查被监视的键是否至少有一个已经被修改过了。如果是,服务器则拒绝执行事务并向客户端返回代表事务执行失败的空回复。每个redis数据库都保存着一个watched_keys字典,这个字典的键是某个被watch命令监视的数据库键,而字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端:在这里插入图片描述
所有对数据库进行修改命令,在执行之后都会对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的数据库键,如果有,则会将监视被修改键的reids_dirty_cas标识打开,表示该客户端的事务安全性已经被破坏。如果在事务提交时,检测到该标识被打开,则会拒绝执行它们提交的事务,以此来保证事务的安全性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值