Redis的事务以一个MULTI命令开始,接着将多个命令放入事务中,最后由EXEC命令将这个事务提交
MULTI
SET "name" "Practical Common Lisp"
GET "name"
SET "author" "Peter Seibel"
Get "auther"
EXEC
事务的实现
Redis客户端中存在一个事务队列,一旦MULTI
开启事务后,后续的所有命令都会存放在事务队列中,直到'EXEC'命令,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行命令所得的结果全部返回给客户端
WATCH命令是一个乐观锁,它可以监视redis数据库中的某个键,一旦事务提交时发现监视的键被修改了,事务就会执行失败,确保事务的安全性
事务的ACID原子性
我觉得redis是不能保证事务的原子性的。
redis事务失败有两种情况,第一种是在事务提交时提交了错误的命令,这种情况在事务提交时就能检查出来,因此该事务所有的命令都不会被执行
MULTI
SET msg "hello"
GET #这是一条错误的命令
#ERR wrong number of arguments for 'get' command
GET msg
EXEC
第二种情况是,某些命令在事务执行时才发现是错误的,但在这种情况下,事务中的正确命令仍然会被执行
SET msg "hello"
MULTI
SADD fruit "apple" "banana" "cherry"
RPUSH msg "good bye" "bye bye" #错误地对字符串键msg执行列表键的命令
SADD alphabet "a" "b" "c"
需要注意的是,redis的事务不支持回滚,原因在于redis作者认为事务回滚这种复杂的功能和Redis追求简单高效的设计主旨不相符,并且他认为,Redis事务的执行时错误通常都是编程错误产生的,这种错误通常只会出现在开发环境中,而很少会在实际生产环境中出现,所以他认为没有必要为Redis开发事务回滚功能
一致性
redis能够保证事务的一致性。
即使在服务器停机时,仍然可以借助RDB和AOF保证事务的一致性
隔离性
因为redis总是以单线程的方式执行命令,并且保证事务不会被中断,因此能够保证隔离性
持久性
redis能否保证持久性,取决于redis采用何种级别的持久化功能