8.redis事务
redis事务本质:一组命令一起执行!一个事务中的所有命令都会被序列化,在被事务执行的过程中,会被顺序执行!
一次性,顺序性,排他性!
1.redis单条命令是保证原子性的,但是事务是不保证原子性的(redis事务没有隔离级别的概念)
redis事务的步骤:
1.开启事务(multi)
2.命令入队(同时执行多条命令:...)
3.执行命令()
!事务每次执行完后就没有了!
案例:
127.0.0.1:6379> MULTI(开启事务)
OK
127.0.0.1:6379> set k1 v1(放入第一条命令)
QUEUED
127.0.0.1:6379> set k2 v2(放入第二条命令)
QUEUED
127.0.0.1:6379> get k2(放入第三条命令)
QUEUED
127.0.0.1:6379> set k3 v3(放入第四条命令)
QUEUED
127.0.0.1:6379> EXEC(执行事务)
1) OK(第一条事务的返回)
2) OK(第二条事务的返回)
3) "v2"(第三条事务的返回)
4) OK(第四条事务的返回)
1.放弃事务:DISCARD
127.0.0.1:6379> MULTI(开启事务)
OK
127.0.0.1:6379> set k1 v1(放入命令)
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> set k3 v3
QUEUED
127.0.0.1:6379> DISCARD(放弃事务)
OK
127.0.0.1:6379> exec(执行出错)
(error) ERR EXEC without MULTI
127.0.0.1:6379> get k2(获取为nil)
(nil)
2.命令出错的两种情况
2.1类比于java的编译异常(代码有问题或命令有错)-->事务中的所有命令都不会执行
127.0.0.1:6379> MULTI(开启事务)
OK
127.0.0.1:6379> set k1 v1(正确命令1)
QUEUED
127.0.0.1:6379> getset k2(错误命令2)
(error) ERR wrong number of arguments for 'getset' command
127.0.0.1:6379> set k3 v3(正确命令3)
QUEUED
127.0.0.1:6379> exec(执行事务:发现错误的命令会导致事务整体无法执行)
(error) EXECABORT Transaction discarded because of previous errors.
2.2类比java中的运行时异常(例如代码中的1/0)-->如果事务队列中存在语法性,那么执行命令时,其他命令可以正常执行,错误命令抛出异常!
127.0.0.1:6379> MULTI(开启事务)
OK
127.0.0.1:6379> set k1 v1(第一条命令)
QUEUED
127.0.0.1:6379> INCR k1(字符串+1操作,执行会报错!)
QUEUED
127.0.0.1:6379> set k2 v2(第三条命令)
QUEUED
127.0.0.1:6379> get k2(获取k2值)
QUEUED
127.0.0.1:6379> exec
1) OK(set k1 v1)
2) (error) ERR value is not an integer or out of range(字符串+1操作执行出错)
3) OK(set k2 v2)
4) "v2"(获取k2的值)
结论:发现redis的单条命令保证原子性,但是事务无法保证原子性,如上述,虽然事务中的一个命令执行失败了,但是不影响事务中其他的命令执行!