Redis总结 -- Redis事务

事务是数据库中的一个非常重要的问题,无论在学习关系型数据库还是菲关系型数据库,事务都会是一个学习的重点

一,Redis中事务的特点

  • 隔离,事务是一个隔离的操作,事务中的所有命令都会被序列化,然后按顺序之心,在执行过程中不会被其他客户端发送过来的命令请求所打断,会在事务中的命令全部被执行完后再去执行其他请求

  • 原子,事务中的命令要么全部被执行,要么全部不执行

  • redis中事务和关系型数据库中事务的不同点就是,redis事务命令中有一条执行出错,其他命令还是会正常执行

二,redis事务的执行

  • multi :开启事务,语句后的命令将会进入执行队列,直到exec才会被执行原子操作

  • exec :执行事务

  • discard : 回滚事务

>	MULTI OK
>	INCR	foo QUEUED
>	INCR	bar QUEUED
>	EXEC 
1)	(integer)	1 
2)	(integer)	1

EXEC 命令的回复是一个数组, 数组中的每个元素都是执行事务中的命令所产生的回复。 其 中, 回复元素的先后顺序和命令发送的先后顺序一致。
当客户端处于事务状态时, 所有传入的命令都会返回一个内容为 QUEUED 的状态回复 (status reply), 这些被入队的命令将在 EXEC 命令被调用时执行。

三,redis中事务的注意问题

1.事务在exec前命令入队时出错

对于发生在 EXEC 执行之前的错误,客户端以前的做法是检查命令入队所得的返回值:如果 命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败。如果有命令在入队时失 败,那么大部分客户端都会停止并取消这个事务。

不过,从 Redis 2.6.5 开始,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务。 在 Redis 2.6.5 以前, Redis 只执行事务中那些入队成功的命令,而忽略那些入队失败的命 令。

2.事务在exec后命令出错

至于那些在 EXEC 命令执行之后所产生的错误, 并没有对它们进行特别处理: 即使事务中有 某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。

3.redis事务不支持回滚,为什么?

Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用 在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误 造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。 鉴于没有任何机制能避免程序员自己造成的错误, 并且这类错误通常不会在生产环境中出 现, 所以 Redis 选择了更简单、更快速的无回滚方式来处理事务。

所以,当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中 退出:

redis>	SET	foo	1 OK
redis>	MULTI OK
redis>	INCR	foo QUEUED
redis>	DISCARD OK
redis>	GET	foo "1"

2.redis中watch作用

watch可以为redis事务提供监视作用

即,被watch监视的键如果在调用exec前被修改,则该整个事务会被取消,exec返回多条空回复(null)

为什么这样做?

举个例子, 假设我们需要原子性地为某个值进行增 1 操作(假设 INCR 不存在)。

首先我们可能会这样做:

val	=	GET	mykey 
val	=	val	+	1 
SET	mykey	$val

上面的这个实现在只有一个客户端的时候可以执行得很好。 但是, 当多个客户端同时对同一 个键进行这样的操作时, 就会产生竞争条件

所以使用watch可以很好地解决该问题

WATCH	mykey
val	=	GET	mykey 
val	=	val	+	1
MULTI 
SET	mykey	$val 
EXEC

如果你使用 WATCH 监视了一个带过期时间的键, 那么即使这个键过期了, 事务仍然可以正 常执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值