跳转至

Redis_03-事务:PY管道and乐观锁

管道

  • 流水线机制: 将所有的命令打包一次型发送给服务器,减少请求次数
  • 在使用Redis连接对象创建管道的时候默认已经开启事务
  • 管道与Redis连接对象可以使用的方法与属性是一样的(操作相同的)
  • 管道内的命令默认会添加到事务中, 事务中的操作是取不到结果的
  • 管道提交事务时,将管道内的事务一并发送给Redis服务器,并返回执行结果(命令的返回值)
from redis import StrictRedis

# 创建Redis链接对象
rds_conn = StrictRedis(host='192.168.31.134', port=6379, db=0, decode_responses=True) # 

# 创建管道
pipeline = rds_conn.pipeline()

# 管道添加命令
a = pipeline.set('stu2', 'WangLin')
b = pipeline.get('stu2')

# 提交事务
ret = pipeline.execute()

# 打印上方的输出结果
print(a) # 取不到的
print(b) # 取不到的
print(ret) # 取出执行结果, 执行 len11 成功为 True, 执行 len12 返回值 'Wanglin'

关闭事务

  • 单独使用流水线机制,关闭事务,以提高事务产生的性能损耗
  • 在使用Redis连接对象创建管道的时候传入参数transaction=False即可关闭事务
from redis import StrictRedis
rds_conn = StrictRedis(host='192.168.31.134', port=6379, db=0, decode_responses=True)
pipeline = redis_client.pipeline(transaction=False)
# 后续的命令都会加入管道
pipeline.get('age')
pipeline.set('age', 20)
# 将管道中的命令打包发送给服务器
ret = pipeline.execute()
print(ret)

乐观锁

  • Redis数据库链接管道使用watch方法设置数据监听, 注意!一旦设置监听数据, 就不会再默认开启事务, 后续的操作就会变成立即执行
  • 在有对监听数据操作的时候,会对数据进行校验,如果操作时的数据跟当时取出来的不同,执行管道内的事物的时候会报错
  • 手动开启事物:管道使用multi方法
  • 可以对下方代码进行Debug: # 对len25进行debug, 假设num原本为3,所以这里取到的也是3,在节点走到len25行阻塞的时候,手动在redis数据库中修改原num的值,这里会执行失败实现
  • 乐观锁避免了数据更新丢失问题
while True:
    try:
        from redis import StrictRedis

        # 创建Redis链接对象
        rds_conn = StrictRedis(host='192.168.31.134', port=6379, db=0, decode_responses=True)

        # 创建管道
        pipeline = rds_conn.pipeline()

        # 设置数据的监听
        pipeline.watch('num')

        # 立即执行并返回结果
        num = pipeline.get('num')

        # 从这之后的操作,手动开启事务
        pipeline.multi()

        # 设置数据
        print(num)
        pipeline.set('num', int(num)*2) # 如果监听的数据(num)发生过变化(这里的num是上面取到的),会报错

        # 提交事物
        ret = pipeline.execute()
        print(ret)

        # 执行到这一步说明事务执行成功(终止循环)
        break
    except Exception as e:
        print(e)
        continue # 如果事务提交失败说明监听的数据遭到了修改或者其他,跳过此次循环让其再执行一边事物