学习Redis,day11 Redis事务操作~

92 阅读3分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

Redis事务操作

Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:

  • 批量操作在发送 EXEC 命令前被放入队列缓存。
  • 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
  • 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。

事务遵循四大性质(ACID):

  • 原子性:指一个事务内的所有操作都是一个整体,因此只有所有的操作都完全执行成功,该事务方可以认为提交成功。如果在提交事务过程中某一条命令语句执行失败,则整个事务必须回滚到事务提交前的状态。
  • 一致性:指事务在完成的时候,必须要保证所有的数据都保持一致的状态,而落实到数据库的各个组成部分上,则要求开发人员能够保证数据在事务前后具备一致性。
  • 隔离性:核心思想就是不同的并发事务对数据产生的修改必须是相互隔离的,假设有两个不同的事务A和B并发执行,那么对A来讲,它在执行前的状态只有两种,即B执行前和B执行后。同理,对B来讲同样是如此,这样的特性我们就称为隔离性。
  • 持久性:指事务完成以后它对数据的影响是永久性的。

redis的事务执行流程︰

  • 开启事务(MULTI)
  • 命令入队()
  • 执行事务(exec)

1、开始事务MULTI

2、执行事务EXEC

3、放弃事务DISCARD

正常执行事务

 127.0.0.1:6379> MULTI               #开启事务
 OK
 #命令入队
 127.0.0.1:6379(TX)> set k1 v1
 QUEUED
 127.0.0.1:6379(TX)> set k2 v2
 QUEUED
 127.0.0.1:6379(TX)> get k2
 QUEUED
 127.0.0.1:6379(TX)> set k3 v3
 QUEUED
 127.0.0.1:6379(TX)> exec            #执行事务
 1) OK
 2) OK
 3) "v2"
 4) OK

放弃事务(放弃执行事务)

 127.0.0.1:6379> MULTI               #开始事务
 OK
 127.0.0.1:6379(TX)> set k1 v1
 QUEUED
 127.0.0.1:6379(TX)> set k2 v2
 QUEUED
 127.0.0.1:6379(TX)> set k4 v4
 QUEUED
 127.0.0.1:6379(TX)> DISCARD         #放弃事务
 OK
 127.0.0.1:6379> get k4              #事务队列中的命令都不会被执行!
 (nil)

编译型异常(代码有问题!命令有错!),事务中所有的命令都不会被执行!

 127.0.0.1:6379> MULTI                   #开始事务
 OK
 127.0.0.1:6379(TX)> set k1 v1
 QUEUED
 127.0.0.1:6379(TX)> set k2 v2
 QUEUED
 127.0.0.1:6379(TX)> set k3 v3
 QUEUED
 127.0.0.1:6379(TX)> getset k3           #错误语句
 (error) ERR wrong number of arguments for 'getset' command
 127.0.0.1:6379(TX)> set k4 v4
 QUEUED
 127.0.0.1:6379(TX)> set k5 v5
 QUEUED
 127.0.0.1:6379(TX)> exec                #执行事务
 (error) EXECABORT Transaction discarded because of previous errors.
 127.0.0.1:6379> get k5                  #获取事务中执行所创建的对象
 (nil)

运行时异常(eg:1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常!

 127.0.0.1:6379> set k1 v1
 OK
 127.0.0.1:6379> MULTI           #开始事务
 OK
 127.0.0.1:6379(TX)> INCR k1     #设置k1自增(允许自增类型为int,double),在运行时会发生错误!
 QUEUED
 127.0.0.1:6379(TX)> set k2 v2
 QUEUED
 127.0.0.1:6379(TX)> set k3 v3
 QUEUED
 127.0.0.1:6379(TX)> get k3
 QUEUED
 127.0.0.1:6379(TX)> exec        #执行事务
 1) (error) ERR value is not an integer or out of range  #虽然第一条命令报错了,但是依旧正常执行成功了!
 2) OK
 3) OK
 4) "v3"
 127.0.0.1:6379> get k2
 "v2"
 127.0.0.1:6379> get k3
 "v3"

明天继续加油!