zoukankan      html  css  js  c++  java
  • redis事务,分布式锁

    事务:一组命令集合

    主要命令multi 和exec

    multi
    set a 1
    sadd s1 a
    ......
    exec
    

    错误处理

    • (1)语法错误
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set a 1
    QUEUED
    127.0.0.1:6379> set b
    (error) ERR wrong number of arguments for 'set' command
    127.0.0.1:6379> seta c
    (error) ERR unknown command 'seta'
    127.0.0.1:6379> exec
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get a
    (nil)
    127.0.0.1:6379> 
    
    

    只要有任何一个语法错误,正确的也不会执行

    • (2)运行错误
      比如a是string类型,然后按照hash操作 hset a k1 v1
    127.0.0.1:6379> keys *
    (empty list or set)
    127.0.0.1:6379> set a 1
    OK
    127.0.0.1:6379> type a
    string
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set n 1
    QUEUED
    127.0.0.1:6379> hset a k1 v1
    QUEUED
    127.0.0.1:6379> set m 2
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    3) OK
    127.0.0.1:6379> mget n m
    1) "1"
    2) "2"
    127.0.0.1:6379> type a
    string
    

    正确的指令是被执行了,redis事务不支持回滚,所以需要开发者自己处理
    开发中规范键名,一般不会出现这种问题

    DISCARD取消事务

    分布式锁

    setnx a:lock 1
    expire a:lock 5
    del a:lock
    
    为了使setnx和expire能一起执行,而expire的执行又依赖setnx是否成功,显然放事务里是不成立的

    setnx和expire组合在一起的原子指令

    set a:lock 1 ex 10 nx

    以上是这只a:lock 为1 有效期为10s的原子操作

    超时问题

    Redis 的分布式锁不能解决超时问题,如果在加锁和释放锁之间的逻辑执行的太长,以至于超出了锁的超时限制,就会出现问题。因为这时候第一个线程持有的锁过期了,临界区的逻辑还没有执行完,这个时候第二个线程就提前重新持有了这把锁,导致临界区代码不能得到严格的串行执行。

    为了避免这个问题,Redis 分布式锁不要用于较长时间的任务。如果真的偶尔出现了,数据出现的小波错乱可能需要人工介入解决

  • 相关阅读:
    利用binlog2sql闪回丢失数据
    MySQL 5.7基于GTID的主从复制
    执行SQL查询导致磁盘耗尽故障演示
    mysqld_safe之三言两语
    利用MyFlash闪回丢失数据(续)
    泛型方法的局限及解决之道
    操作系统学习笔记:文件系统实现
    动态绑定滚动条事件
    asp.net mvc + javascript导入文件内容
    asp.net mvc + javascript生成下载文件
  • 原文地址:https://www.cnblogs.com/HKUI/p/10508007.html
Copyright © 2011-2022 走看看