文章目录
一、什么是redis事务?
1. redis pipeline机制
- redis pipline是一个客户端提供的机制,不是服务端提供;通过一次发送多次请求命令,从而减少网络传输的时间。
- 注意:pipeline不具备事务性;事务性是指一组操作要么全部成功执行,要么全部失败回滚,中间不能只执行一部分。这种特性通常用于数据库或数据操作中,保证数据的一致性和可靠性,
2. redis事务
事务是指 用户定于一系列数据库操作,这些操作视为一个完整的逻辑处理单元,要么全部执行,要么全部不执行,是不可分割的工作单元。
+多核情况 探讨原子操作(避免其他线程执行)
+多条并发连接 探讨事务
事务原语(MULTI | EXEC | DISCARD | WATCH)
- MULTI 开启事务 (begin / strat transaction)
MULTI开启事务,事务执行过程中,单个命令是入队列操作,直到
调用EXEC才会一起执行;乐观锁实现,所以失败需要重试; - EXEC 提交事务 (commit)
提交事务 - DISCARD 取消事务 (rollback)
取消事务 - WATCH 监听事务
检测key的变动,若在事务执行中,key变动则取消事务;在事务开启前调用,乐观锁(cas)实现;若被取消则事务返回nil
乐观锁和悲观锁
乐观锁(redis):
“我假设你不会碰我操作的变量,冲突很少,出问题我再处理。”
悲观锁(mysql):
“我假设你一定会碰,所以我提前上锁,防止你碰。”
对比项 | 乐观锁(Optimistic Lock) | 悲观锁(Pessimistic Lock) |
---|---|---|
核心假设 | 不会发生冲突 | 一定会发生冲突 |
操作方式 | 不加锁,操作前后做数据校验 | 操作前加锁,阻塞其他操作 |
并发性能 | 性能好,冲突少时效率高 | 并发低,阻塞多时效率低 |
实现方式 | 版本号(version)、时间戳等 | 数据库 select … for update、行锁等 |
失败处理 | 操作失败后重试 | 先加锁,保证别人不能动 |
典型场景 | 数据读多写少,如缓存、排行榜更新 | 数据写多读多,如账户转账、订单处理 |
事务原语的应用
【1. 事务实现 zpop】
WATCH zset
element = ZRANGE zset 0 0
MULTI
ZREM zset element
EXEC
-----------------------------------
【2. 事务实现 加倍操作】
WATCH score:10001
val = GET score:10001
MULTI
SET score:10001 val*2
EXEC
实操
3. lua脚本
redis内部嵌有lua虚拟机,实际开发不用四个事务,而是用lua脚本实现原子性。
【1.调用方式】
redis.call("命令",key1,key2,