Redis之事务

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis之事务

事务

关系型数据库通常会通过事务保证ACID,即原子性、隔离性、持久性、一致性,Redis虽然也有事务,但是没法完全支持事务的这几种特性,

Redis是单线程的,所以符合事务的隔离性,同时Redis具备备份功能,也符合持久性,但是一致性和原子性是没有的。

基本用法

关系型数据库的事务指令一般是begin(开始)、commit(提交)、rollback(回滚)三者。

begin();
try {
    command1();
    command2();
    commit();
} catch (Exception e) {
    rollback();
}

redis也有三个与之对应,multi(开始)、exec(执行)、discard(丢弃)。


127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> incr test

QUEUED

127.0.0.1:6379(TX)> incr test

QUEUED

127.0.0.1:6379(TX)> exec

1) (integer) 1

2) (integer) 2

当事务multi开始时,之后的所有指令都将被存在服务端的一个事务队列中,最终服务端收到exec指令时,才开始执行整个事务队列,执行完毕后一次性返回所有的运行结果,

因为redis的单线程特性,不用担心事务指令队列执行时被其他指令打搅,所以redis事务是可以保证隔离性的。

下图是事务执行的完成过程,multi开启一个事务,服务端返回OK,后续的操作服务端都返回QUEUE,这意味着指令都被放入到队列中,等到exec时,服务端开始执行并返回结果。

image.png

redis事务没有原子性

事务的原子性是指事务要么完全成功,要么全部失败,而Redis是不支持事务原子性的可以用下面的demo演示,

通过结果可以看到,事务中最后一个指令执行失败了,因为data的值并不是一个数值,所以无法自增,根据原子性此时应该失败,但是下面的将data设置为hi依然执行了,并且事务结束后我们获取到的也是hi,

redis事务执行时出现执行失败后续的指令依然会得到执行,所以说redis事务是没有原子性的。

127.0.0.1:6379> get data

"nihao"

127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> set data hello

QUEUED

127.0.0.1:6379(TX)> incr data

QUEUED

127.0.0.1:6379(TX)> set data hi

QUEUED

127.0.0.1:6379(TX)> exec

1) OK

2) (error) ERR value is not an integer or out of range

3) OK

127.0.0.1:6379> get data

"hi"

discard (放弃执行)

discard指令用于丢弃事务缓存的指令队列里的所有指令,当然要在exec指令前执行,可以看到下面的demo,discard后,meta依然是nil,并没有发生指令执行的情况。

127.0.0.1:6379> get meta

(nil)

127.0.0.1:6379> multi

OK 

127.0.0.1:6379(TX)> incr meta

QUEUED

127.0.0.1:6379(TX)> incr meta

QUEUED

127.0.0.1:6379(TX)> discard

OK

127.0.0.1:6379> get meta

(nil)

使用管道优化

Redis事务每次发送指令也会造成一次网络读写,当事务的指令较多,也会造成网络耗时的开销,所以一般事务可以搭配管道技术一起使用,节约网络开销,使程序更快。

watch指令

watch指令用在事务开始之前,监控一个变量,当事务开始执行时,发现该变量的值和watch时的值不一样,将会终止执行,并返回一个null给客户端。

一般业务场景中可以用做乐观锁,例如需要读取redis中的某个值在内存中做计算,最后把计算的值放回去,因为这个过程不是原子性的,很有可能读写过程中有别的线程把这个值改了并存到了redis中,这会造成混乱,

使用redis锁可以防止这个问题,但是分布式锁是悲观锁,如果并没有人在这期间修改该值,也造成了获取锁和释放锁的资源浪费,根据上面的描述watch比较适合做这个事情,

在事务开始前watch住该值,如果事务exec时发现该值没有改变,则正常执行,否则返回null告诉客户端执行失败,客户端做重试或其他业务逻辑处理。

需要注意的是redis进制在multi和exec执行watch,否则会出错 ERR WATCH inside MULTI is not allowed

在下方demo中,使用了watch来对redis中的一个key进行自增操作,最终的值正确为10,watch在其中配合事务做出了乐观锁的效果,颇有CAS的味道。

image.png

image.png

代码地址:https://github.com/qiaomengnan16/redis-demo/tree/main/redis-watch

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
8月前
|
NoSQL Redis 数据库
10- 你们用过Redis的事务吗 ? 事务的命令有哪些 ?
```markdown Redis事务包括MULTI、EXEC、DISCARD、WATCH四个命令。虽具备事务功能,但在实际开发中使用较少。 ```
81 7
|
8月前
|
NoSQL Redis 数据库
什么是Redis的事务?
Redis事务提供原子性和顺序性,确保命令按顺序执行且不被打断。核心概念包括原子性、顺序性、隔离性和持久性。关键指令有MULTI、EXEC、DISCARD和WATCH,用于事务的开始、执行、取消和监视。这保障了命令的完整性,防止并发操作导致的数据不一致。
65 2
|
3月前
|
缓存 NoSQL Redis
Redis 事务
10月更文挑战第18天
35 1
|
8月前
|
缓存 NoSQL 数据处理
Redis事务悄然而至:命令的背后故事
Redis事务悄然而至:命令的背后故事
62 0
|
8月前
|
NoSQL Redis
Redis事务:保证数据操作的一致性和可靠性
Redis事务:保证数据操作的一致性和可靠性
127 0
|
5月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
11天前
|
NoSQL Redis
Redis事务长什么样?一文带你全面了解
Redis事务是一组命令的有序队列,通过MULTI、EXEC、WATCH和DISCARD等命令实现原子性操作。事务中的命令在EXEC执行前不会实际运行,而是先进入队列,确保所有命令要么全部成功,要么全部失败。此外,Redis还支持Lua脚本实现类似事务的操作,通常更简单高效。事务适用于购物车结算、秒杀活动、排行榜更新等需要保证数据一致性的场景。
35 0
|
3月前
|
SQL 分布式计算 NoSQL
大数据-42 Redis 功能扩展 发布/订阅模式 事务相关的内容 Redis弱事务
大数据-42 Redis 功能扩展 发布/订阅模式 事务相关的内容 Redis弱事务
32 2
|
3月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
428 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
5月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀