事务
执行一组命令,按顺序地串行执行而不会被其它命令插入
事务作用
一个队列中,一次性、顺序性、排他性的执行一系列命令
事务相关命令以及操作
1 discard # 取消 2 exec # 执行所有事务块内的命令 3 multi # 标记一个事务块的开始 4 unwatch # 取消对所有key的监视 5 watch # 监视一个或多个key
事务的正常操作、放弃操作、全体连坐、冤头债主
1 # ---------------正常操作------------------------- 2 127.0.0.1:6379> keys * 3 (empty list or set) 4 127.0.0.1:6379> MULTI 5 OK 6 127.0.0.1:6379> set k1 v1 7 QUEUED 8 127.0.0.1:6379> set k2 v2 9 QUEUED 10 127.0.0.1:6379> get k2 11 QUEUED 12 127.0.0.1:6379> set k3 v3 13 QUEUED 14 127.0.0.1:6379> EXEC 15 1) OK 16 2) OK 17 3) "v2" 18 4) OK 19 127.0.0.1:6379> keys * 20 1) "k2" 21 2) "k1" 22 3) "k3" 23 # -------------------取消操作------------------ 24 127.0.0.1:6379> MULTI 25 OK 26 127.0.0.1:6379> set k1 v1 27 QUEUED 28 127.0.0.1:6379> set k2 22 29 QUEUED 30 127.0.0.1:6379> DISCARD 31 OK 32 127.0.0.1:6379> get k2 33 "v2" 34 # --------------------全体连坐------------------- 35 127.0.0.1:6379> MULTI 36 OK 37 127.0.0.1:6379> set k1 v1 38 QUEUED 39 127.0.0.1:6379> set k2 v2 40 QUEUED 41 127.0.0.1:6379> set k3 v3 42 QUEUED 43 127.0.0.1:6379> getset k3 44 (error) ERR wrong number of arguments for 'getset' command 45 127.0.0.1:6379> set k4 v4 46 QUEUED 47 127.0.0.1:6379> EXEC 48 (error) EXECABORT Transaction discarded because of previous errors. 49 127.0.0.1:6379> get k4 50 (nil) 51 127.0.0.1:6379> set k1 aa 52 OK 53 127.0.0.1:6379> get k1 54 "aa" 55 127.0.0.1:6379> keys * 56 1) "k2" 57 2) "k1" 58 3) "k3" 59 # ---------------------冤头债主(可以看出支持部分事务)------------- 60 127.0.0.1:6379> MULTI 61 OK 62 127.0.0.1:6379> INCR k1 63 QUEUED 64 127.0.0.1:6379> set k2 22 65 QUEUED 66 127.0.0.1:6379> set k3 33 67 QUEUED 68 127.0.0.1:6379> set k4 44 69 QUEUED 70 127.0.0.1:6379> get k4 71 QUEUED 72 127.0.0.1:6379> EXEC 73 1) (error) ERR value is not an integer or out of range 74 2) OK 75 3) OK 76 4) OK 77 5) "44" 78 127.0.0.1:6379> get k4 79 "44"
watch监控
悲观锁:认为一定有人改 整张表锁定 并发性差,一致性好
乐观锁:我认为数据不会被修改 不锁表 保证并发 一致性 它在一条数据之后加上Version版本号 如果现在有两人操作这条数据,那么后提交的人就要从新再数据库拿到之前提交的那个人的版本号做修改之后再提交CAS(Check And Set)
表锁:整张表锁定,并发性极差,一致性好
行锁:缩小范围,只对行进行锁定
watch指令类似乐观锁
1 # 第一个终端 2 127.0.0.1:6379> keys * 3 1) "debt" 4 2) "k1" 5 3) "k3" 6 4) "k4" 7 5) "k2" 8 6) "balance" 9 127.0.0.1:6379> set debt 0 10 OK 11 127.0.0.1:6379> set balance 100 12 OK 13 127.0.0.1:6379> WATCH balance 14 OK 15 127.0.0.1:6379> MULTI 16 OK 17 127.0.0.1:6379> DECRBY balance 20 18 QUEUED 19 127.0.0.1:6379> INCRBY debt 20 20 QUEUED 21 127.0.0.1:6379> EXEC 22 1) (integer) 80 23 2) (integer) 20 24 # ---------------------------加锁----------------------- 25 127.0.0.1:6379> WATCH balance 26 OK 27 127.0.0.1:6379> MULTI 28 OK 29 127.0.0.1:6379> DECRBY balance 20 30 QUEUED 31 127.0.0.1:6379> INCRBY debt 20 32 QUEUED 33 127.0.0.1:6379> EXEC 34 (nil) 35 127.0.0.1:6379> get balance 36 "800" 37 127.0.0.1:6379> get debt 38 "20" 39 # --------------------------------unwatch不加锁---------------- 40 127.0.0.1:6379> WATCH balance 41 OK 42 127.0.0.1:6379> set balance 500 43 OK 44 127.0.0.1:6379> UNWATCH 45 OK 46 127.0.0.1:6379> WATCH balance 47 OK 48 127.0.0.1:6379> MULTI 49 OK 50 127.0.0.1:6379> set balance 80 51 QUEUED 52 127.0.0.1:6379> set debt 20 53 QUEUED 54 127.0.0.1:6379> EXEC 55 1) OK 56 2) OK 57 58 # 第二个终端 59 [root@localhost ~]# redis-cli 60 127.0.0.1:6379> keys * 61 1) "debt" 62 2) "k1" 63 3) "k3" 64 4) "k4" 65 5) "k2" 66 6) "balance" 67 127.0.0.1:6379> get debt 68 "20" 69 127.0.0.1:6379> get balance 70 "80" 71 # ------------------------加锁-------------------------- 72 127.0.0.1:6379> set balance 800 73 OK 74 127.0.0.1:6379> 75 # -----------------------不加锁unwatch------------------ 76 127.0.0.1:6379> get balance 77 "500"