redis事务以及watch的理解

69 篇文章 0 订阅
40 篇文章 0 订阅

redis事务以及watch的理解

 

2018.05.14 12:04 字数 28 阅读 156评论 0喜欢 0

事务的特性

1.原子性,数据库事务中的多个操作,要么同时执行成功,要么一个也不执行,执行的时候将事务中的命令入队列,
当客户端发送执行命令时,将命令依次执行,如果遇到回滚操作,则抛弃该事务中队列的命令.
2.一致性,数据库在执行事务之前一致的,那么执行之后也一致,这其中的一致是说,数据库中没有产生一些无法解释的数据,
在redis中,主要有三种方式保证事务的一致性
    a.入队错误,如发送一个错误的命令,服务器拒绝执行
    b.执行错误,当命令能够入队,但是在实际执行中发生错误,服务器不会对数据进行修改
    c.服务器宕机
        I.无持久化模式下,重启后数据库数据丢失
        II.备份模式下,数据会进行恢复
3.隔离性,隔离性的本质是,多个事务并发执行,使其串行执行,redis本身是采用单线程,因此,redis的事务总是以
串行的方式允许(个人理解:当我开启一个事务未提交,在另外开启一个事务,这两个是串行执行的,其中因为是单线程,所以不会用阻塞的方法来阻止事务的提交,
我认为,实际只有当真正去提交时,才会去修改数据库中的数据,隔离性出现解决的问题就是脏读,幻读,不可重复读,当a事务发起一堆执行执行,b事务在获取时,
读取的依旧是数据库本身的值,而a事务在获取值时,给他返回的是queued,也就不存在脏读,幻读,不可重复读,因为读取的值看不见,实际上是并未实现真正的隔离性)
4.持久性,redis是存在内存中,有自己的持久化机制,如rdb,aof

实现的机制

1.首先介绍下redis事务的相关命令:multi:开启事务,exec:执行事务,discard:回滚操作,相对应于mysql,分别为begin,commit,rollback
2.事务的实现:
事务的实现从开始到结束通常会经历三个阶段:
    a.事务开始阶段

image.png

    b.命令入队列
    当事务执行时,redis客户端有自己的事务状态,状态中含有一个事务队列以及已入队列命令的计数器,命令按照fifo的方式进入队列,事务队
    列是一个multiCmd的数组,每个multiCmd结构都保存了一个已入队命令的相关信息,整个事务状态以及multiCmd的结构如下

image.png

    c.事务执行
    当处于事务状态的客户端向服务器发送exec命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将结果返回给客户端

WATCH

WATCH是一个乐观锁,它可以在exec命令执行之前,监视任意数量的数据库键,并在exec命令执行时,检查被监视的键是否至少有一个已经被修改过了,如果是
服务器则拒绝执行事务,并向客户端返回代表事务执行失败的空回复.
例如:
时间AB
T1watch name
T2multi
T3set name pmj
T4 set name Pmj
T5exec
此时当A事务提交时,发现name的值已经被修改,此时服务器拒绝执行A事务,并向客户端A返回空回复

原理

每个redis数据库都保存着一个watched_keys字典,这个字典的键是某个被watch命令监视的数据库键,而字典的值则是一个链表,链表中记录了所有监视相应数据库键的客户端,数据结构如下图:

image.png

所有对数据库进行修改命令,在执行之后都会对watched_keys字典进行检查,查看是否有客户端正在监视刚刚被命令修改过的数据库键,如果有,则会将监视被修改键的reids_dirty_cas标识打开,
表示该客户端的事务安全性已经被破坏.如果在事务提交时,检测到该标识被打开,则会拒绝执行它们提交的事务,以此来保证事务的安全性.

[参考自redis设计与实现:第19章 事务]

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值