[关闭]
@a5635268 2016-02-28T15:05:53.000000Z 字数 1295 阅读 1135

【redis专题(11)】事务

Redis


Redis支持简单的事务,所谓简单是因为其不支持回滚(回滚是用队列模仿的),与mysql有以下区别

mysql redis
开启 start transaction
语句 普通sql
失败 rollback 回滚
成功 commit

rollback与discard的区别:
如果已经成功执行了2条语句, 第3条语句出错
Rollback后,前2条的语句影响消失。
discard只是取消队列,并非回滚。要用在exec前面;

在mutil后面的语句中, 语句出错可能有2种情况:

1: 语法就有问题,
这种,exec时,报错, 所有语句得不到执行

2: 语法本身没错,但适用对象有问题. 比如 zadd 操作list对象
Exec之后,会执行正确的语句,并跳过有不适当的语句.
(如果zadd操作list这种事怎么避免? 这一点,由程序员负责)

Example

  1. 127.0.0.1:6379> multi #开启事务
  2. OK
  3. 127.0.0.1:6379> decrby zz 100
  4. QUEUED
  5. 127.0.0.1:6379> incrby xx 100
  6. QUEUED
  7. 127.0.0.1:6379> exec
  8. 1) (integer) 900
  9. 2) (integer) 900
  10. 127.0.0.1:6379> multi
  11. OK
  12. 127.0.0.1:6379> decrby zz 100
  13. QUEUED
  14. 127.0.0.1:6379> sadd zz haha #语法本身没有错,那整个事务中的语句都会执行;
  15. QUEUED
  16. 127.0.0.1:6379> exec
  17. 1) (integer) 800
  18. 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

悲观锁与乐观锁

场景如下:

我正在买票
Ticket -1 , money -100
而票只有1张, 如果在我multi之后,和exec之前, 票被别人买了---即ticket变成0了.
我该如何观察这种情景,并不再提交

Redis的事务中,启用的是乐观锁,只负责监测key没有被改动.具体的命令:watch命令

watch key1 key2  ... keyN

作用: 监听key1 key2..keyN有没有变化,如果有变, 则事务取消

unwatch 

作用: 取消所有watch监听

  1. redis 127.0.0.1:6379> watch ticket
  2. OK
  3. redis 127.0.0.1:6379> multi
  4. OK
  5. redis 127.0.0.1:6379> decr ticket
  6. QUEUED
  7. redis 127.0.0.1:6379> decrby money 100
  8. QUEUED
  9. redis 127.0.0.1:6379> exec #在exec之前该数据在其他session有改动就取消事务,返回nil
  10. (nil)
  11. redis 127.0.0.1:6379> get ticket
  12. "0"
  13. redis 127.0.0.1:6379> get money
  14. "200"
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注