• Redis(五)事务


    Redis(五)事务

    引用wiki中关于事务处理的定义:

    Transaction processing is information processing in computer science that is divided into individual, indivisible operations called transactions. Each transaction must succeed or fail as a complete unit; it can never be only partially complete.

    在计算机科学中,事务处理被分割成单个的、不可分割的操作叫做事务。事务特性是要么成功,要么失败。

    Redis为什么需要事务

    Redis是单线程,本身设计上保证了单个命令的执行具有线程安全。但是批命令操作,如何保证原子性?如:

    1. set k v;
    2. del k v;

    这种两个命令的操作,需要原子性:要么全部被执行成功,要么全部执行失败。

    Redis的事务特性

    在Redis中事务需要保证两点:

    • 原子性:要么全部执行要么全部不执行,主要通过multi和exec保证;
    • 隔离性:批命令的执行中,不可再插入其他客户端请求的命令的执行;

    Redis事务和DB事务的区别

    原子性上的差异,DB事务中原子性保证要么全部被执行成功要么全部不执行(回滚)。Redis中的原子性表明要么全部被执行(有些命令可能会执行失败,执行失败并不回滚,后续会介绍)要么全部不执行。

    DB事务的需要保证ACID特性,在事务的要求上更加的苛刻严格。Redis的事务特性只需要遵循以上两点特征。

    对于Redis和DB事务的隔离性有很大差异,切勿弄混。Redis的隔离性是指事务操作中不可有其他的客户端命令的执行,而DB事务的隔离性更多是在数据可见性上的保证。

    Redis事务是不支持回滚的。Redis认为操作失败只会因为命令语法导致错误,这种情况下,应该是开发测试中予以解决。还有回滚必然会影响Redis的性能。

    如下:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k v
    QUEUED
    127.0.0.1:6379> set m n
    QUEUED
    127.0.0.1:6379> set x y
    QUEUED
    127.0.0.1:6379> lpush x i e
    QUEUED
    127.0.0.1:6379> hset k key value
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) OK
    3) OK
    4) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    5) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    127.0.0.1:6379> get k
    "v"
    127.0.0.1:6379> get x
    "y"
    127.0.0.1:6379> 
    

    前三个set命令都执行成功,但是后续的lpush、hset因为操作的key类型不对,全部失败,但是事务并没有回滚。但是Redis保证了事务的原子性——全部执行。

    Redis对事务的支持

    Redis主要是通过multi/exec/discard/watch几个命令操作实现对事务的支持的。

    • multi开启一个事务
    • exec执行提交事务
    • discard废弃事务
    • watch监视键值
    1. 原理:在Redis中通过维护队列的方式实现事务,将事务中批操作全部按顺序入队,在exec时,再批量执行。

    2. 错误处理:不同Redis版本在入队时遇到异常的处理情况是不一样的。Redis 2.6.5以后是入队前检查操作的正确性(如命令的参数数量错误),如果有错误,将返回错误响应,同时会将错误的命令操作记录,在执行exec时,判断是否有错误记录,如果有,放弃事务执行。这样方便流水线pipeline操作,减少client和redis server的通信。
      exec执行时遇到的错误(如操作命令如key不符),redis的处理方式是忽略执行错误的操作,继续处理后续操作。

    3. 上面原理介绍到multi开始事务,后续命令都会入队。所以只要将队列情况就可以废弃当前事务。

    4. 在DB中为了保证数据的一致性时,通常都是提供锁操作,比如Mysql中update时会有排它锁。但是Redis中并不是这样,因为排它锁属于悲观锁的一种,会对性能大打折扣。Redis提供了乐观锁机制给应用保证数据的一致性。
      watch操作:Redis在开启事务之前,可以对事务中修改的key进行watch监视,在事务exec时,如果key在之前被其他的客户端修改,那么将放弃此次事务。watch可以在事务开始之前被调用多次,也可以一次调用监视多个key。
      乐观锁的机制在java中的提现就是cas操作。关于乐观锁,后面会开相关的文章。

    Redis中的另一种事务支持

    在Redis2.6以后的版本中,除了以上的方式对事务的支持,Redis引入的Lua脚本方式也可以用于事务场景。在Redis中脚本的执行更加的简单和快速。

    持久化对Redis事务的影响

    当使用AOF方式持久化时,Redis会使用单个的write命令进行系统调用将事务写入磁盘。

    参考

    Transactions

  • 相关阅读:
    简述序列化与反序列化
    更新Kali源&&Docker vulhub 安装
    超级弱口令爆破工具&&hydra
    通达OA任意用户登录
    读书笔记——白帽子讲Web安全
    骑士CMS搭建与利用
    记一次DVWA的SQL注入测试
    网络基础
    C#类对象的事件定义
    [开源]FreeSCADA的通道数据与控件属性关联以及自动刷新机制研究
  • 原文地址:https://www.cnblogs.com/lxyit/p/9828851.html
Copyright © 2020-2023  润新知