Python redis事务(乐观锁与悲观锁)

python 专栏收录该内容
2 篇文章 0 订阅

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
  • 0
    点赞
  • 0
    评论
  • 4
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

挖坑程序员

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值