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

    Redis支持简单的事务


    Redis与mysql事务的对比



    Mysql

    Redis

    开启

    start transaction

    muitl

    语句

    普通sql

    普通命令

    失败

    rollback 回滚

    discard 取消

    成功

    commit

    exec


    : rollback与discard 的区别

    • 如果已经成功执行了2条语句, 第3条语句出错.
    • Rollback后,前2条的语句影响消失.
    • Discard只是结束本次事务,前2条语句造成的影响仍然还在


    :

    mutil后面的语句中, 语句出错可能有2种情况

    1.  语法就有问题,

    这种,exec时,报错, 所有语句得不到执行

            2.   语法本身没错,但适用对象有问题. 比如zadd 操作list对象

    Exec之后,会执行正确的语句,并跳过有不适当的语句.

    (如果zadd操作list这种事怎么避免? 这一点,由程序员负责)    需要程序员手动控制操作



    思考:

    我正在买票

    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
    redis 127.0.0.1:6379> exec
    (nil) // 返回nil,说明监视的ticket已经改变了,事务就取消了.
    redis 127.0.0.1:6379> get ticket
    "0"
    redis 127.0.0.1:6379> get money
    "200"


    watch key1 key2 ... keyN

    作用:监听key1 key2..keyN有没有变化,如果有变, 则事务取消


    unwatch

    作用: 取消所有watch监听

     

    下面的内容转载自http://haili.me/archives/439.html

     

     

    先介绍下与Redis的Transaction(事务)相关的几个命令:
    WATCH 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断;
    UNWATCH 取消 WATCH 命令对所有 key 的监视;
    MULTI 标记一个事务块的开始,指事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由EXEC命令原子性(atomic)地执行;
    DISCARD 取消事务,放弃执行事务块内的所有命令;
    EXEC 执行所有事务块内的命令;

     

     

    redis> MULTI
    OK
    redis> INCR user_id
    QUEUED
    redis> INCR user_id
    QUEUED
    redis> INCR user_id
    QUEUED
    redis> PING
    QUEUED
    redis> EXEC
    1) (integer) 1
    2) (integer) 2
    3) (integer) 3
    4) PONG

     

    phpredis也对该方法做了实现。

    事务的调用有两种模式

    Redis::MULTI

    Redis::PIPELINE

    默认是Redis::MULTI模式,Redis::PIPELINE管道模式速度更快,但没有任何保证原子性有可能造成数据的丢失。
    Redis管道PHP测试示例:

    <?php
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $startTime = microtimeFloat();
    
    $pipe = $redis->multi(Redis::PIPELINE);
    for($i = 0; $i < 100000; $i++){
        $pipe->set("key::$i", time());
        $pipe->get("key::$i");
    }
    $pipe->exec();
    
    //$redis->flushDB();
    $endTime = microtimeFloat();
    $runTime = $endTime - $startTime;
    echo "用时 $runTime 秒";
    
    function microtimeFloat(){
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
    }
    ?>

     

     

     

     

     

     

  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/timelesszhuang/p/4376141.html
Copyright © 2011-2022 走看看