Redis不是传统意义上的关系型数据库,它是一个速度非常快的非关系型内存数据库,它可以存储键(KEY)与5种不同类型的值(VALUE)之间的映射,
可以将存储在内存中的键值对数据持久化到硬盘,可以使用复制特性来扩展读取性能,还可以使用客户端分片来扩展写性能。
Redis的事务与传统关系数据库的事务并不相同。在关系数据库中,用户首先向数据库服务器发送BEGIN,然后执行各个相互一致的写操作和读操作,
最后,用户可以选择发送COMMIT来确认之前所做的修改,或者发送ROLLBACK来放弃那些修改。
关系型数据在执行事务操作时,会对访问的数据进行加锁(表锁、行级锁),直到事务被提交(COMMIT)或被回滚(ROLLBACK)为止。
如果有其他客户端试图对被加锁的数据进行修改,那么该客户端将被阻塞,直到事务执行完毕锁释放为止。
缺点在于资源竞争的问题严重,并且持有锁的客户端运行越慢,等待解锁的客户端被阻塞的时间就越长。
这样的加锁被称作:悲观锁(pessimistic locking)。
但是,Redis没有加锁!Redis的事务使用WATCH观察事务中数据的变化,如果被其他客户端抢险修改了数据,则事务的执行被取消。
这样的做法被称作:乐观锁(optimistic locking)。
这样做好处在于没有资源竞争,并且客户端在直到自己执行失败后,重试就可以。
1、MULTI 命令
用于开始一个事务,其后可以添加多个命令入队到事务中,最后由EXEC命令触发事务的执行。
在添加命令入队列的过程中发生错误,最终EXEC执行时会发生错误。
127.0.0.1:6379> MULTI -
例如,
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> PING QUEUED 127.0.0.1:6379> EXEC 1) (integer) 1 2) (integer) 0 3) PONG
发生错误
127.0.0.1:6379> MULTI OK 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> INCR trans -1 (error) ERR wrong number of arguments for 'incr' command 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> PING QUEUED 127.0.0.1:6379> EXEC (error) EXECABORT Transaction discarded because of previous errors.
2、EXEC 命令
用于出发事务的执行。在添加命令入队列的过程中发生错误,最终EXEC执行时会发生错误。
使用WATCH命令时,在开始一个事务队列后,如果有元素的值被修改,事务执行时被终端,并且返回nil。
127.0.0.1:6379> EXEC -
例如,
127.0.0.1:6379> WATCH trans OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET trans 10 QUEUED 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> EXEC 1) OK 2) (integer) 11 3) (integer) 12 4) (integer) 11 5) (integer) 10
使用WATCH后,如果KEY的值被别的终端修改,则执行EXEC时会被中断。
127.0.0.1:6379> WATCH trans OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET trans 10 QUEUED 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> INCR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> EXEC (nil)
3、WATCH 命令
用于观察一个或多个键的值是否发生变化。
如果在事务执行之前观察的键值发生变化,事务将被中断执行。
127.0.0.1:6379> WATCH key [key ...]
例如,
127.0.0.1:6379> WATCH trans id name OK
4、UNWATCH 命令
用于取消对所有键的观察。
127.0.0.1:6379> UNWATCH -
例如,
127.0.0.1:6379> WATCH trans id name OK 127.0.0.1:6379> UNWATCH OK
5、DISCARD 命令
用于取消事务队列中已经加入的操作。
127.0.0.1:6379> DISCARD -
例如,
127.0.0.1:6379> WATCH trans OK 127.0.0.1:6379> MULTI OK 127.0.0.1:6379> SET trans 10 QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> DECR trans QUEUED 127.0.0.1:6379> DISCARD OK 127.0.0.1:6379> EXEC (error) ERR EXEC without MULTI