事务是数据库的一个重要功能。所谓事务,就是指对数据进行读写的一系列操作。Redis通过MULTI、EXEC、WATCH等命令来实现事务功能:
redis> MULTI
OK
redis> SET "name" "mike"
QUEUED
redis> GET "age"
QUEUED
redis> EXEC
1) OK
2) 20
复制代码
该事务首先以一个MULTI命令开始,接着将多个命令放入事务当中,最后由EXEC命令将这个事务提交给服务器。
其中:
WATCH命令是Redis保证事务的乐观锁(optimistic locking),在EXEC命令执行之前,监视人意数量的数据库键,并在EXEC执行之后,检查被监视的键是否被修改。如果有一个键被修改,服务器会拒绝执行事务,确保事务的安全性。
事务在执行时,会提供专门的属性保证,包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),也就是 ACID 属性。这些属性既包括了对事务执行结果的要求,也有对数据库在事务执行前后的数据状态变化的要求。针对这四个性质,Redis做了如下内容:
原子性
对于Redis的事务功能来说,事务队列中的命令要么就全部执行,要么就一个都不执行,因此,Redis的事务时具有原子性的。Redis事务和关系型数据库事务的最大区别在于,Redis不支持事务回滚机制(作者觉得不符合Redis的定位),即使事务队列中某个命令执行期间出现了错误,整个事务也会继续执行下去,命令错误有三种情况:
一致性
事务具有一致性是指:如果数据库在执行事务之前是一致的,那么在事务执行之后,无论事务是否成功,数据库应该也是一致的。事务的一致性收到错误命令和实例故障的影响:
隔离性
事务的隔离性是指,在多事务并发执行时,各个事务之间不会互相影响,并且在并行或串行执行事务产生的结果完全相同。由于Redis的乐观锁机制,保证了并行状态下的事务执行隔离性,如果并发操作在EXEC命令之后被服务端执行,那么久相当于单线程操作,也是保证隔离性的。
持久性
事务的持久性指的是在事务执行完毕时,执行这个事务所得到的结果已经被保存在永久性存储介质里,执行事务的结果不会丢失。但对于Redis来说,无论是否开启RDB或者AOF的情况下,都会存在数据丢失的情况,所以无法保证事务的持久性。