redis事务

database

简介

可以一次执行多个命令,本质是一组命令的集合.

一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入,不许加塞

作用

在一个队列中,一次性,顺序性,排他性的执行一系列命令

开启事务示例

remoteSelf:1>multi

"OK"

remoteSelf:1>set k1 v1

"QUEUED"

remoteSelf:1>set k2 v2

"QUEUED"

remoteSelf:1>get k1

"QUEUED"

remoteSelf:1>exec

1) "OK"

2) "OK"

3) "v1"

放弃事务

remoteSelf:1>mget k1 k2

1) "v1"

2) "v2"

remoteSelf:1>multi

"OK"

remoteSelf:1>set k1 11

"QUEUED"

remoteSelf:1>set k2 22

"QUEUED"

remoteSelf:1>discard

"OK"

remoteSelf:1>mget k1 k2

1) "v1"

2) "v2"

一个失败所有的都失败(如果打完命令就报错,此时全部回滚)

remoteSelf:1>keys *

1) "k2"

2) "k1"

3) "website"

4) "zset01"

remoteSelf:1>multi

"OK"

remoteSelf:1>set k3 v3

"QUEUED"

remoteSelf:1>set k4 v4

"QUEUED"

remoteSelf:1>getset k4

"ERR wrong number of arguments for 'getset' command"

remoteSelf:1>exec

"EXECABORT Transaction discarded because of previous errors."

remoteSelf:1>keys *

1) "k2"

2) "k1"

3) "website"

4) "zset01"

一个失败其他的成功(如果打完命令没有报错,进入队列,运行时报错,则其他的运行成功,报错的失败)

remoteSelf:1>keys *

1) "k2"

2) "k1"

3) "website"

4) "zset01"

remoteSelf:1>mget k1 k2

1) "v1"

2) "v2"

remoteSelf:1>multi

"OK"

remoteSelf:1>incr k1

"QUEUED"

remoteSelf:1>set k3 v3

"QUEUED"

remoteSelf:1>exec

1) "ERR value is not an integer or out of range"

2) "OK"

remoteSelf:1>keys *

1) "website"

2) "zset01"

3) "k1"

4) "k2"

5) "k3"

watch监控.如果监控的数据发生了改变,则事务失效

悲观锁

pessimistic lock,每次拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,

这样别人想拿这个数据就会block直到拿到锁.

传统的关系型数据库里边就用到了很多这种锁机制,比如行所,表锁等,读锁,写锁等,都是在操作之前先上锁

乐观锁

optimistic lock,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,

可以使用版本号等机制.乐观锁适用于多读的应用类型,这样可以提高吞吐量.

乐观锁策略: 提交版本必须大于记录当前版本才能执行更新

示例

127.0.0.1:8686[1]> mget balance debt

1) "100"

2) "0"

127.0.0.1:8686[1]> watch balance

OK

# watch之后执行更改balance

remoteSelf:1>set balance "200"

"OK"

remoteSelf:1>get balance

"200"

127.0.0.1:8686[1]> multi

OK

127.0.0.1:8686[1]> decrby balance 20

QUEUED

127.0.0.1:8686[1]> incrby debt 20

QUEUED

# 执行失败

127.0.0.1:8686[1]> exec

(nil)

watch

watch指令,类似乐观锁,事务提交时,如果key的值已经被别的客户端改变,整个事务队列都不会被执行.

通过watch命令在事务执行之前监控了多个keys,倘若在watch之后有任何key的值发生了变化,

exec命令执行的事务都被放弃,同时返回Nullmulti-bulk应答已通知调用者事务执行失败

exec执行之后会取消对所有key的监控

127.0.0.1:8686[1]> get test

"10"

127.0.0.1:8686[1]> mget balance debt

1) "200"

2) "0"

127.0.0.1:8686[1]> watch balance test

OK

127.0.0.1:8686[1]> multi

OK

# 另外一个客户端改变balance的值

remoteSelf:1>set balance "100"

"OK"

remoteSelf:1>get balance

"100"

127.0.0.1:8686[1]> incr balance

QUEUED

127.0.0.1:8686[1]> decr debt

QUEUED

# 执行事务失败

127.0.0.1:8686[1]> exec

(nil)

127.0.0.1:8686[1]> mget balance debt

1) "100"

2) "0"

127.0.0.1:8686[1]> get test

"10"

# 之前已经监控了test不在监控

# 修改test的值

remoteSelf:1>set test "20"

"OK"

remoteSelf:1>get test

"20"

127.0.0.1:8686[1]> multi

OK

127.0.0.1:8686[1]> incr test

QUEUED

# 事务执行成功.证明了exec在执行时,会取消对所有key的监控

127.0.0.1:8686[1]> exec

1) (integer) 21

unwatch会取消所有key的监控

以上是 redis事务 的全部内容, 来源链接: utcz.com/z/532185.html

回到顶部