005、Redis的事物
本文最后更新于 66 天前,其中的信息可能已经过时,如有错误请发送邮件到wuxianglongblog@163.com

Redis的事物

一.简要阐述MySQL事务和Redis事务的区别

    MySQL的事务:
        基于事物日志,悲观锁机制,MVCC,ISOLASTION等机制一起保证,属于强事务支持。
        在MySQL中我们执行一个事务其实是在COMMIT之前就已经修改数据了,但底层是通过隔离级别,MVCC,redo log,undo log来实现数据的一致性。

    Redis的事务:
        基于队列实现的,Redis是乐观锁机制,仅实现了原子性的保证,属于弱事务支持。
        在Redis中事务被提交到队列,如果我们不想执行事务可以将对应的事务操作从队列中删除即可。需要注意的是,Redis中的事务提交到队列后,并不会对原数据进行修改,直到调用了EXEC指令后才会执行事务哟。

    温馨提示:
        综上所述,Redis的事务我们生产环境中并不会经常性使用,因为它仅实现了原子性,对于持久性,隔离性,一致性的并没有实现。因此如果非要用事务的话可以考虑MySQL,Oracle之类的数据库。
        但是我们对于Redis事务这一块的知识点多少是要了解一点的,因为这也是面试的一个高频问点。

二.Redis事务的实战案例

1.Redis事务初体验

    (1)单独开启一个终端执行事务:
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> MULTI  # 有点类似于MySQL的"BEGIN"指令,意义在于开启事务!
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET name oldboyedu  # 注意观察,此指令被提交到队列中,并没有被真正执行,下同。
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET age 18
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *  # 注意观察,当前的事务已经被提交到队列中,但并未真正执行!
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> EXEC  # 当我们调用了EXEC指令,表示执行当前事务,则会创建此事务中的两个KEY哟~
        OK
        OK
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        age
        name
        127.0.0.1:6379[13]> 

    (2)在另一个终端单独开启一个事务,在上面的终端执行"EXEC"指令之前后,可以尝试获取KEY,是否可以拿到数据:
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET name  # 很明显,当开启的事务未执行EXEC指令,我们是获取不到数据的!

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> get age

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET name  # 但当开启的事务执行了EXEC指令后,我们是可以获取到数据的哟~
        oldboyedu
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> get age
        18
        127.0.0.1:6379[13]> 

2.Redis默认就是乐观锁机制,多个事务可以对同一个KEY进行操作

    (1)终端1执行的指令
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> MULTI
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET address 北京朝阳
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> EXEC  # 请让终端2先执行EXEC指令后再来执行该指令,以方便看到实验效果
        OK
        address
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        address
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET address
        北京朝阳
        127.0.0.1:6379[13]> 

    (2)终端2执行的指令
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> MULTI
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET address 北京海淀
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> EXEC
        OK
        address
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        address
        age
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET address  # 请让终端1先执行EXEC指令后再来执行该指令,以方便看到实验效果
        北京朝阳
        127.0.0.1:6379[13]> 

3.Redis可以使用WATCH指令来监控一个KEY,若该KEY被其它的事务操作过,则本次事务执行失败。WATCH指令对于数据一致性要求较高的场景很有用,比如买飞机票,火车票等场景,一张票(ticket)只能卖给一个人

    (1)终端1执行的指令:
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> WATCH name  # 监控name这个KEY,如果该KEY被其它事务修改,则本次事务失效!
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> MULTI
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET name JasonYin  # 为name的KEY赋值
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> EXEC  # 执行时没有任何输出,说明本次事务未执行成功。请让终端2先执行EXEC指令后再来执行该指令,以方便看到实验效果哟~

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *  # 尽管上一条命令的事务未执行成功,但其它事务是执行成功的,因此我们可以看到该KEY.
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET name
        oldboyedu
        127.0.0.1:6379[13]> 

    (2)终端2执行指令
        [root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
        127.0.0.1:6379[13]> KEYS *

        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> MULTI
        OK
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> SET name oldboyedu
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        QUEUED
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> EXEC  # 请让终端1先执行EXEC指令之前的所有指令后再来执行该指令,以方便看到实验效果哟~
        OK
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> KEYS *
        name
        127.0.0.1:6379[13]> 
        127.0.0.1:6379[13]> GET name
        oldboyedu
        127.0.0.1:6379[13]> 

4.使用"DISCARD"指令可以丢弃当前事务

[root@redis201.oldboyedu.com ~]# redis-cli -a oldboyedu2021 -n 13 --raw
127.0.0.1:6379[13]> KEYS *
name
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> MULTI
OK
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> SET age 18
QUEUED
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> set address BeiJing
QUEUED
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> KEYS *
QUEUED
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> DISCARD  # 执行该指令后,则当前事务的所有已经提交到队列的指令都将被删除!换句话说,就是放弃本次事务!
OK
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> KEYS *
name
127.0.0.1:6379[13]> 
127.0.0.1:6379[13]> QUIT
[root@redis201.oldboyedu.com ~]# 
谨此笔记,记录过往。凭君阅览,如能收益,莫大奢望。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇