Redis事务
Redis事务
1. 介绍
- 事务:
- 事务是一个单独的隔离操作:事务中的命令都会序列化,按顺序执行。事务在执行的过程中,不会被其他客户端发送的消息打断。
- 事务是一个原子操作:事务中的命令要么全部执行,要么全部不执行。
- 命令:
- MULTI:事务开始的标记
- EXEC:执行事务中的命令
- DISCARD:刷新事务中的命令
- WATCH:标记key可能存在冲突,需要监视
2. 命令
2.1 MULTI
命令:MULTI
命令说明:事务的开始标记
返回值:OK
2.2 EXEC
命令:EXEC
命令说明:事务执行。
返回值:执行结果。
2.3 DISCARD
命令:DISCARD
命令说明:放弃事务。
返回值:OK
2.4 WATCH
命令:WATCH
命令说明:监视key。在执行了WATCH之后,只要指定的key有操作,那么,在WATCH后面的exec之前的事务都不会执行。当执行了exec后,不管事务成功与否,都会去除监视。
2.5 事务异常
- 事务执行异常
注意:事务中的命令执行异常不会阻止事务的执行。
- 事务创建异常
注意:事务中的命令如果出现语法异常,那么操作入队失败。
3. redis为什么不支持事务回滚
如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。
以下是这种做法的优点:
- Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。
- 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。
有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。
4. redis 持久化与事务
当使用 AOF 方式做持久化的时候, Redis 会使用单个 write(2) 命令将事务写入到磁盘中。
然而,如果 Redis 服务器因为某些原因被管理员杀死,或者遇上某种硬件故障,那么可能只有部分事务命令会被成功写入到磁盘中。
如果 Redis 在重新启动时发现 AOF 文件出了这样的问题,那么它会退出,并汇报一个错误。
使用redis-check-aof
程序可以修复这一问题:它会移除 AOF 文件中不完整事务的信息,确保服务器可以顺利启动。
从 2.2 版本开始,Redis 还可以通过乐观锁(optimistic lock)实现 CAS (check-and-set)操作。