• redis 事务(悲观锁和乐观锁)


    MULTI

      开启事务,后续的命令会被加入到同一个事务中

      事务中的操作会发送给客服端,但是不会立即执行,而是将操作放到了该事务对应的一个队列中,服务端返回QUEQUD

    EXEC

      执行EXEC后,事务中的命令才会执行

      事务中的命令出错时,不会回滚也不会停止,而是继续执行下一步操作

    DISCARD

      取消事务,事务队列会被清空

    原子性:不支持,不会回滚且继续执行,

    隔离性:支持,事务中的命令顺序,不会被打断,先EXEC先执行,单机redis读写操作使用单进程单线程

    持久性:不支持,redis 数据容易丢失

    一致性:不支持,要求通过乐观锁watch来实现

    redis 非 事务型管道:

    from redis import StrictRedis
    
    # 创建redis客户端 decode_response = true 从redis中获取的数据会进行decorade,不会是byse类型
    redis_client = StrictRedis(host='127.0.0.1',port=6379,db=0,decode_response=True)
    
    # 创建管道  默认就会开启事务,(设置参数,transaction=False,则不会开启事务,只会开启管道)
    pipe = redis_client.pipeline(transaction=False)
    
    # 使用管道对象进行的操作
    a = pipe.set('name', 'zhangsan')
    b = pipe.get('name')
    
    # 不会提交事务  只是将管道打包提交给redis服务器
    c = pipe.execute()
    
    print(a, b, c)

     事务型管道:

    #创建客服端
    redis_client = StrictRedis()
    
    #创建管道,默认会开启事务
    pipe = redis_client.pipeline()
    
    #使用管道对象进行操作,都会放入事务中
    a = pipe.set('name':'zs')
    b = pipe.get('name')
    
    #提交事务,提交事务后才会执行
    c = pipe.execute()
    print(a,b,c)

    乐观锁:watch

      redis实现乐观锁机制

      机制:开启事务前,设置对数据的监听,EXEC时,如果发生数据发生过修改,事务会自动取消(DISCARD)

      事务EXEC后,无论成败,监听会被移除

    redis 乐观锁代码:

    from redis import StrictRedis, WatchError
    
    # 创建客户端
    redis_client = StrictRedis(host='127.0.0.1',port=6379,db=0,)
    # 创建管道
    pipe = redis_client.pipeline()
    
    
    while True:
        try:
            # 开启数据的监听  一旦调用watch, 后续操作会立即执行(后续操作不会添加到事务中)
            pipe.watch('reserve_count')
    
            # 获取库存数量
            count = pipe.get('reserve_count')
            # 判断是否有库存
            if int(count) > 0: # 有库存, 让库存 -1
    
                # 手动开启事务
                pipe.multi()
    
                # 库存-1
                pipe.decr('reserve_count')
    
                # 提交事务
                pipe.execute()
                print('已下单')
    
            else:  # 没有库存
                print('已售罄')
                # 移除监听
                pipe.reset()
    
            break
    
        except WatchError as e:  # 出现该异常, 说明监听的数据被修改了, 重试/取消
            print('重试')

    悲观锁: setnx 建不存在才会设置成功

    setnx和redis 悲观锁代码   

    from redis import StrictRedis
    
    # 创建redis连接
    redis_client = StrictRedis(decode_responses=True)
    
    # 设计redis悲观锁 处理秒杀超卖问题
    
    # 先获取锁
    while True:
        order_lock = redis_client.setnx('lock:order', 1)
    redis_client.expire(
    'lock:order', 2) # 给锁设置过期时间, 避免锁释放失败导致死锁现象 if order_lock: reserve_count = redis_client.get('reserve_count') if int(reserve_count) > 0: redis_client.decr('reserve_count') print("生成订单") else: print("已售罄") # 完成处理, 移除锁 redis_client.delete('lock:order') break
  • 相关阅读:
    【实验吧】藏在图片中的秘密
    pwntools各使用模块简介
    【笔记】shellcode相关整理
    【pwnable】asm之write up
    【实验吧】转瞬即逝write up
    利用wireshark任意获取qq好友IP实施精准定位
    【实验吧】逆向1000
    【实验吧】逆向rev50
    pwnable.kr brainfuck之write up
    JavaScript获取后台C#变量以及调用后台方法
  • 原文地址:https://www.cnblogs.com/wjun0/p/11884240.html
Copyright © 2020-2023  润新知