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的单条命令保证原子性,但是事务无法保证原子性,如上述,虽然事务中的一个命令执行失败了,但是不影响事务中其他的命令执行!

 

posted @ 2022-05-25 21:31  努力的达子  阅读(22)  评论(0编辑  收藏  举报