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

    核心知识点:

    1.事务出错的类型有两种:

    a.语法错误,事务不会被执行;

    b.运行时报错,可能有部分事务会被执行成功。

    2.watch可以监测在执行事务的过程中,如果目标被改变,将会导致事务无法执行。

    熟悉关系型数据库的读者应该对事务比较了解,简单的说,事务表示一组动作,要么全部执行,要么全部不执行。

    Redis提供了简单的事务功能,将一组需要执行的命令放到multi和exec两个命令之间。

    multi命令代表事务开始,exec命令代表事务结束,它们之间的命令是原子顺序执行的。

    例如,如果两个人需要成为好友,需要各自在自己的好友列表中加上对方的命令,如果只完成了一方,那么这组命令应该视作无效。

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> sadd kebi:friend maoxian
    QUEUED
    127.0.0.1:6379> sadd maoxian:friend kebi
    QUEUED

    可以看到sadd命令此时的返回结果是QUEUED,代表命令并没有真正执行,而是暂时保存在Redis中。

    在另外一个客户端查看刚才的添加操作,应该没有结果:

    127.0.0.1:6379> sismember maoxian:friend kebi
    (integer) 0

    只有执行了exec之后,写入操作才算完成。

    127.0.0.1:6379> exec
    1) (integer) 1
    2) (integer) 1

    再次在另外一个客户端查询,有结果:

    127.0.0.1:6379> sismember maoxian:friend kebi
    (integer) 1

    如果事务中命令出现错误,Redis的处理机制也不尽相同,一般主要有两种情况。

    1.命令错误

    如果事务的执行过程中,出现语法错误,会造成整个事务无法执行:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> sadd kebi:friend maoxian
    QUEUED
    127.0.0.1:6379> saddd maoxian:friend kebi
    (error) ERR unknown command 'saddd'
    127.0.0.1:6379> exec
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> sismember kebi:friend maoxian
    (integer) 0   #并没有添加成功

    2.运行时错误

    也许语法不存在问题,但是执行过程中出现了错误,这种情况可能导致部分操作被执行成功。

    (integer) 1
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> sadd kebi:friend xiaoniao
    QUEUED
    127.0.0.1:6379> zadd maoxian:friend 1 xiaoniao
    QUEUED  #并没有语法错误,可maoxian:friend是集合,不是有序集合
    127.0.0.1:6379> exec
    1) (integer) 1
    2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    127.0.0.1:6379> sismember kebi:friend xiaoniao
    (integer) 1
    127.0.0.1:6379> sismember maoxian:friend xiaoniao
    (integer) 0

    可以看到错误只是部分,但是并不是所有结果都没有执行,这就会导致问题。

    Redis并不支持回滚功能,开发人员需要自己修复这类问题。

    有些应用场景在事务之前,确保事务中的key没有被其他客户端修改过,才执行事务,否则不执行。Redis提供了watch命令来解决这类问题。

    #客户端1
    127.0.0.1:6379> set key java
    OK
    #客户端1
    127.0.0.1:6379> watch key
    OK
    #客户端1
    127.0.0.1:6379> multi
    OK
    #客户端2
    127.0.0.1:6379> append key python
    (integer) 10
    #客户端1
    127.0.0.1:6379> append key linux
    QUEUED
    #客户端1
    127.0.0.1:6379> exec
    (nil)
    #客户端1
    127.0.0.1:6379> get key
    "javapython"

    可以看到,如果在执行exec之前,所需的数据被修改了将会导致事务不能被执行。

    Redis提供了简单的事务功能,之所说它简单,主要是因为它不支持事务中的回滚特性,

    同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的“keep it simple”的特性。

  • 相关阅读:
    Android项目实战(五十五):部分机型点击home再点图标进入程序不保留再之前界面的问题
    Android项目实战(五十四):zxing 生成二维码图片去除白色内边距的解决方案
    关于RecyclerView嵌套导致item复用异常,界面异常的问题
    191114
    191112
    191111
    191110
    191109
    191108
    191107
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/8098996.html
Copyright © 2011-2022 走看看