相关链接
1. 事务
Redis单条命令是保证原子性的,但是事务不保证原子性。一个事务中所有的命令都会被序列化(事务执行的过程中,会按照顺序执行)
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。 ? 原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。 隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。 持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
Redis事务的三个特性:一次性、顺序性、排他性。 ? 一次性:在一个队列里一次性执行。 顺序性:按照顺序执行。 排他性:执行事务过程中不允许被干扰。 ? Redis事务是没有隔离级别的概念,所有命令在事务中,并没有直接被执行,只有发起执行命令的时候才会执行。
------ 队列 set set set 执行 ------
Redis事务 ??● 开启事务( Multi ) ??● 命令入队( 其他命令… ) ??● 执行事务( exec ) / 放弃事务 ( discard )
1.1 执行事务
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> get k2
QUEUED
127.0.0.1:6379(TX)> set k3 v3
QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) OK
3) "v2"
4) OK
1.2 放弃事务
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> discard
OK
127.0.0.1:6379> get k1
(nil)
2. 事务异常
2.1 编译型异常
??编译型异常(命令有误,不能通过编译),事务中所有的命令都不会执行。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> zet k3
(error) ERR unknown command `zet`, with args beginning with: `k3`,
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1
(nil)
2.2 运行时异常
??运行时异常(例如1/0),如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行的,错误命令抛出异常。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> geoadd china:city 39.91667 116.41667 beijing
QUEUED
127.0.0.1:6379(TX)> set k1 v1
QUEUED
127.0.0.1:6379(TX)> exec
1) (error) ERR invalid longitude,latitude pair 39.916670,116.416670
2) OK
127.0.0.1:6379> get k1
"v1"
3. 监控实现乐观锁
Redis监控:watch、unwatch
mysql悲观锁:很悲观,认为任何时候都会出问题,无论做什么都要加锁。 mysql乐观锁:很乐观,认为什么时候都不会出问题,所以不会上锁。 ???1) 获取version ???2) 更新数据的时候判断一下version字段是否和之前记录的一致(是否有人修改过这个数据)
3.1 监控 正常执行
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set in 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch in
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby in -20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
3.2 监控 执行失败
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money
OK
...
127.0.0.1:6379> get money
"0"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> set money 0
OK
...
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby money 20
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby money 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 120
3.2 监控 事务成功后,监视自动关闭
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby money 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 120
127.0.0.1:6379> get money
"120"
127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> set money 120
OK
...
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> incrby money 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 140
22/03/07
M
|