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