zoukankan      html  css  js  c++  java
  • redis05----Redis 中的事务

    Redis支持简单的事务

    Redismysql事务的对比

    Mysql

    Redis

    开启

    start transaction

    multi

    语句

    普通sql

    普通命令

    失败

    rollback 回滚

    discard 取消(不叫回滚,是队列里面的命令不执行,队列里面的任务根本就没有执行。而不是执行了也可以撤回来)

    成功

    commit

    exec

    注: rollback与discard 的区别
    如果已经成功执行了2条语句, 第3条语句出错.
    Rollback后,前2条的语句影响消失.
    Discard只是结束本次事务,前2条语句造成的影响仍然还在。严格来讲不叫回滚,只是叫取消。Redis的事务相对要简单。
    r1:2>set wang 100
    "OK"
    
    r1:2>set zhao 100
    "OK"
    
    r1:2>multi
    "OK"
    
    r1:2>decrby zhao 100
    "QUEUED"     //减100并没有执行,而是加入到了队列中,redis是单进程的,exec的时候就回去执行队列里面的语句
    
    r1:2>incrby wang 100
    "QUEUED"
    r1:2>get wang
    "QUEUED"
    
    r1:2>get zhao
    "QUEUED"
    r1:2>exec 
    注:
    在mutil后面的语句中, 语句出错可能有2种情况
    1: 语法就有问题, 
    这种,exec时,报错, 所有语句得不到执行
    r1:2>multi
    "OK"
    
    r1:2>decrby zhao 100
    "QUEUED"
    
    r1:2>sdsv 
    "ERR unknown command 'sdsv'"
    
    r1:2>exec
    "EXECABORT Transaction discarded because of previous errors."   //事务取消了,zhao没有减100
    
    2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象
    Exec之后,会执行正确的语句,并跳过有不适当的语句.
    r1:2>multi
    "OK"
    
    r1:2>decrby zhao 100
    "QUEUED"
    
    r1:2>sadd wang pig    //wang是一个字符串,这里当成是集合在处理
    "QUEUED"   //放在队列里面,命令尚没有执行,
    r1:2>exec
    1) "0"        //zhao的钱变为了0
    2) "WRONGTYPE Operation against a key holding the wrong kind of value"     //第二个语句执行出错
    
    (如果zadd操作list这种事怎么避免? 这一点,由程序员负责)
    Multi是把命令放在一个队列里面,exec是真正的执行,语法错误则都不执行,语法没错但是适用对象有错则执行正确的语句跳过错误的语句。这就没法保证原子性。
    
    r1:2>multi
    "OK"
    
    r1:2>decrby zhao 100
    "QUEUED"
    
    r1:2>decrby wang 100
    "QUEUED"
    
    r1:2>discard    //取消,就是清空队列,就不会执行了
    "OK"
    r1:2>mget zhao wang
    1) "100"
    2) "100"
    思考: 
    我正在买票
    Ticket -1 , money -100
    而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了---即ticket变成0了.
    我该如何观察这种情景,并不再提交
    
    悲观的想法: 
    世界充满危险,肯定有人和我抢, 给 ticket上锁, 只有我能操作. [悲观锁]
    
    乐观的想法:
    没有那么人和我抢,因此,我只需要注意,
    --有没有人更改ticket的值就可以了 [乐观锁]
    
    Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.
    
    
    具体的命令----  watch命令
    例: 
    redis 127.0.0.1:6379> watch ticket
    OK
    redis 127.0.0.1:6379> multi
    OK
    redis 127.0.0.1:6379> decr ticket
    QUEUED
    redis 127.0.0.1:6379> decrby money 100
    QUEUED
    //现在已经对ticket进行了监控,另外一个窗口将ticket改动了
    另一个窗口:> decr ticket    
    redis 127.0.0.1:6379> exec
    (nil)   // 返回nil,说明监视的ticket已经改动了,事务就取消了.队列就不执行了。
    redis 127.0.0.1:6379>mget ticket money
    "0"
    "200"
    
    watch key1 key2  ... keyN
    作用:监听key1 key2..keyN有没有变化,如果任意一个有变, 则事务取消
    unwatch 
    作用: 取消所有watch监听
  • 相关阅读:
    Update SSM agent to each EC2 via Bat and bash script
    Shell脚本循环读取文件中的每一行
    通过psexec实现远程安装软件包
    Getting Private/Public IP address of EC2 instance using AWS-cli [closed]
    Python to list users in AWS
    BAT script to set local account password never expire
    Difference between Netbios and Host name
    PowerShell官方文档
    powershell for rename server name
    Create a conditional DNS forwarder on our domain.com to Amazon default DNS provider
  • 原文地址:https://www.cnblogs.com/yaowen/p/8276819.html
Copyright © 2011-2022 走看看