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 分布式锁不要用于较长时间的任务。如果真的偶尔出现了,数据出现的小波错乱可能需要人工介入解决

  • 相关阅读:
    Java学习
    Java学习
    2020年11月22日Java学习日记
    2020年11月15日Java学习日记
    2020年11月14日Java学习日记
    2020年11月12日Java学习日记
    Java 网络编程:(一)网络编程基础知识
    Java IO流:(十二)备用
    Java IO流:(十二)commons-io工具类的使用
    Java IO流:(十二)NIO&NIO2简单介绍
  • 原文地址:https://www.cnblogs.com/HKUI/p/10508007.html
Copyright © 2011-2022 走看看