redis-事务

redis-事务

    • 用法
    • 概念
    • 事务中发生错误
    • redis为什么不支持rollback
    • watch

用法

> multi ## multi命令用于开启一个事务,它总是返回 OK 
OK
> set foo 1
QUEUED ## 事务开启以后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中
> incr foo
QUEUED
> exec ## 当EXEC命令被调用时, 所有队列中的命令才会被执行。
1) OK
2) (integer) 2
> get foo
"2"

exec命令的回复是一个数组, 数组中的每个元素都是执行事务中的命令所产生的回复。回复元素的先后顺序和命令发送的先后顺序一致。

另一方面, 通过调用discard, 客户端可以清空事务队列, 并放弃执行事务。

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

概念

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

  • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

exec命令负责触发并执行事务中的所有命令:

  • 如果客户端在使用multi开启了一个事务之后,却因为断线而没有成功执行exec,那么事务中的所有命令都不会被执行。
  • 另一方面,如果客户端成功在开启事务之后执行exec,那么事务中的所有命令都会被执行。

批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到事务里的更新,事务外查询不能看到。没有事务隔离级别的概念

在传统的关系式数据库中,常常用 ACID 性质来检验事务功能的可靠性和安全性。在 Redis 中,事务总是具有原子性(Atomicity)、一致性(Consistency)和隔离性(Isolation),并且当 Redis 运行在某种特定的持久化模式下时,事务也具有持久性(Durability)。

事务中发生错误

使用事务时可能会遇上以下两种错误:

  • 事务在执行exec之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。在客户端调用exec命令时,拒绝执行并自动放弃这个事务。

    MULTI
    +OK
    INCR a b c
    -ERR wrong number of arguments for 'incr' command
    
  • 命令可能在exec调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。不保证原子性

    MULTI
    +OK
    INCR a b c
    -ERR wrong number of arguments for 'incr' command
    

redis为什么不支持rollback

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

watch

watch指令类似于乐观锁,在事务提交时,如果watch监控的多个KEY中任何KEY的值已经被其他客户端更改,则使用EXEC执行事务时,事务队列将不会被执行,同时返回Nullmulti-bulk应答以通知调用者事务执行失败。

你可能感兴趣的:(redis)