redis 流水笔记 五 事务

本文深入探讨Redis事务机制,包括MULTI、EXEC、DISCARD和WATCH命令的使用,事务的原子性和隔离性,以及与RDBMS事务的区别。通过实例演示如何使用WATCH确保事务的一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是事务?

 一组命令按顺序执行,不保证原子性。

MULTIEXECDISCARD and WATCH are the foundation of transactions in Redis. They allow the execution of a group of commands in a single step, with two important guarantees:

  • All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.

  • Either all of the commands or none are processed, so a Redis transaction is also atomic. The EXEC command triggers the execution of all the commands in the transaction, so if a client loses the connection to the server in the context of a transaction before calling the MULTI command none of the operations are performed, instead if the EXEC command is called, all the operations are performed. When using the append-only file Redis makes sure to use a single write(2) syscall to write the transaction on disk. However if the Redis server crashes or is killed by the system administrator in some hard way it is possible that only a partial number of operations are registered. Redis will detect this condition at restart, and will exit with an error. Using the redis-check-aof tool it is possible to fix the append only file that will remove the partial transaction so that the server can start again.

Starting with version 2.2, Redis allows for an extra guarantee to the above two, in the form of optimistic locking in a way very similar to a check-and-set (CAS) operation. This is documented later on this page.

--

 在使用事务改变 值时,可以使用watch 观测,如果改变,事务执行失败

127.0.0.1:6379> set balance 300
OK
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> DECRBY balance 20
QUEUED
127.0.0.1:6379> INCRBY debt 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 280
2) (integer) 40

1  思考,如果在改变某个值时,未做watch测试,会怎么样?

   期望值不同,再种情况,应该必免的。

[root@hadoop03 bin]# ./redis-cli 
127.0.0.1:6379> set debt 900
OK
127.0.0.1:6379> 
#  在执行事务前,我改变了balance 的值,然后在去改变,
127.0.0.1:6379> DECRBY balance 90
QUEUED
127.0.0.1:6379> INCRBY debt 90
QUEUED
127.0.0.1:6379> exec
1) (integer) 810
2) (integer) 990
127.0.0.1:6379> 


2、取消对一个事务的监测 unwatch

---- redis 事务 和 RDMS 事务的区别

 我们知道RDMS 事务如果执行失败,所有的操作都将进行回滚, redis 不是这样的

官网出这样的回答:

     1、在语法层面出现的错误,事务是进行回滚的。

     2、 加入了queue的,出现一条语句出现错误,将会执行剩余的操作,比如:

  • Redis commands can fail only if called with a wrong syntax (and the problem is not detectable during the command queueing), or against keys holding the wrong data type: this means that in practical terms a failing command is the result of a programming errors, and a kind of error that is very likely to be detected during development, and not in production.
  • Redis is internally simplified and faster because it does not need the ability to roll back
127.0.0.1:6379> set  key4  's'
OK
127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> INCR key4
QUEUED
127.0.0.1:6379> set key5 vava
QUEUED
127.0.0.1:6379> exec
1) (error) ERR value is not an integer or out of range
2) OK
127.0.0.1:6379> get key5
"vava"
127.0.0.1:6379> 

 发现 key5 的写入成功了,这也是第二条,部分成功,失败也就失败吧

  在看另一种情况,就是语法出错的同时,导致整个事务全部失败。

127.0.0.1:6379> MULTI 
OK
127.0.0.1:6379> setgsa
(error) ERR unknown command `setgsa`, with args beginning with: 
127.0.0.1:6379> set key6 vav
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get key6
(nil)
127.0.0.1:6379> 

  如何保证事务原子性,在重要的操作前,添加WATCH监测,如果改变,UWATCH 后重新添加监测,执行事务即可。

Watch 是什么?

watch 提供是cas操作,乐观锁,如果watch 监测的key值,在最近一次发现修改,那么整个事务将会执行失败,无论顺序

WATCH is used to provide a check-and-set (CAS) behavior to Redis transactions.

WATCHed keys are monitored in order to detect changes against them. If at least one watched key is modified before the EXEC command, the whole transaction aborts, and EXEC returns a Null reply to notify that the transaction failed.

127.0.0.1:6379> watch balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set key7 val7
QUEUED
127.0.0.1:6379> DECRBY balance 90
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get key7
(nil)
127.0.0.1:6379> 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值