redis单条命令是保证原子性的,但是事物是不保证原子性的。redis的事物就是一条命令一次性执行。redis在执行过程中是按照顺序执行的!
一次性、顺序性和排他性。
redis的事物是没有隔离级别的,在redis里面事物必须是发起命令的时候才会被执行。
redis执行事物顺序: 开启事物(multi) --》命令入队(其他命令) --》执行事物(exec)
127.0.0.1:6379> MULTI 开启事物
OK
127.0.0.1:6379(TX)> set a1 a1 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> set a2 a2 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> get a1 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> set a3 a3 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> EXEC 提交事物,一起执行上面命令
1) OK
2) OK
3) "a1"
4) OK
127.0.0.1:6379> MULTI 开启事物
OK
127.0.0.1:6379(TX)> set w1 w1 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> set w2 w2 命令不执但行不生效
QUEUED
127.0.0.1:6379(TX)> DISCARD 取消事物
OK
127.0.0.1:6379> get w1 上面取消了事物,队列命令都不会被执行
(nil)
127.0.0.1:6379>
在redis事物中,如果是命令错误,所有事物中的命令都不会被执行
127.0.0.1:6379> MULTI 开启事物
OK
127.0.0.1:6379(TX)> set v1 v1 set值
QUEUED
127.0.0.1:6379(TX)> set v2 v2 set值
QUEUED
127.0.0.1:6379(TX)> getset v2 执行错误命令让他报错
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379(TX)> EXEC 提交事物错误,所有命令都不执行
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379>
在redis事物中,如果是执行错误,错误代码以外的其他命令都会被执行
127.0.0.1:6379> MULTI 开启事物
OK
127.0.0.1:6379(TX)> set k1 k1 执行命令但不生效
QUEUED
127.0.0.1:6379(TX)> INCR k1 给K1自增1,这里会异常,K1是字符串
QUEUED
127.0.0.1:6379(TX)> set k2 k2 执行命令但不生效
QUEUED
127.0.0.1:6379(TX)> set k3 k3 执行命令但不生效
QUEUED
127.0.0.1:6379(TX)> get k2 执行命令但不生效
QUEUED
127.0.0.1:6379(TX)> EXEC 提交事务
1) OK 成功
2) (error) ERR value is not an integer or out of range 失败
3) OK 成功
4) OK 成功
5) "k2" 成功
127.0.0.1:6379>
乐观锁和悲观锁 :
redis的乐观锁和悲观锁其实和mysql数据库是的一样的,乐观锁顾名思义就是比较乐观,取数据的时候不加锁,提交数据的时候会去比对一下版本号,如果一致就直接提交,如果不一致就失败,悲观锁的话就是获取数据的时候就上锁了,直到资源操作完成释放资源以后其他获取资源的才能使用。所以redis的悲观锁对性能的影响是很大的。具体的命令就不演示了,只是跟大家说一下这个锁的理念,大家可以去官网查一下redis命令。