1、mysql中只有使用了
InnoDB
引擎的数据库或表才支持事务;
2、使用“事务”的目的是:统一管理insert,update,delete
这些写操作,以此来维护数据的完整性。
事务命令
mysql:
begin #显式地开启一个事务
commit #提交事务,对数据库进行的所有写操作变为永久性的
rollback #结束用户的事务,并撤销正在进行的所有未提交的写操作
redis支持简单的事务:
multi #标记事务的开始
exec #执行事务的commands队列
discard #结束事务,并清除commands队列
通过类比msyql来理解redis的事务命令,很显然,它们有着本质区别。
redis和mysql事务的对比(不能回滚):
mysql redis
开启 start transaction/begin multi
语句 SQL 命令
失败 roolback回滚 discart取消
成功 commit提交 exec执行事务的命令队列
roolback
和discard
的区别:
如果已经成功执行了2条语句,第3条语句出错。roolback
后前面2条语句的影响小时;discard
只是结束本次事务,前面2条语句造成的影响仍然存在。
在multi
后面的语句出错可能有两种情况:
1、语法就有问题。(这种exec时报错,所有语句都不执行)
2、语法本身没有错,但使用对象有问题。比如zadd
命令操作link对象
,exec之后回执行正确的语句并跳过不适当的语句。
思考:悲观锁和乐观锁
我正在买票:
ticket -1;
money -100;
#票减1,钱减100
而如果票只有1张,如果在multi之后exec之前
,票被其他人买走了,即ticket变为0了。
我该如何观察这种情况,并不在提交?
悲观的想法:有人和我抢,给ticket加锁,只有我能操作。(悲观锁)
乐观的想法:我只需要注意有没有人更改ticket的值就可以了。(乐观锁)
redis的事务中,启动的是乐观锁,只负责监测key有没有被改动
Redis Watch 命令
Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断
redis Watch 命令基本语法如下:
WATCH key [key ...]
还是结合上面买票
业务来理解:
redis> watch ticket #监视ticket这个key
OK
redis> multi #开启事务
OK
redis> decr tickert #票减去1(注意我们这里只有一张票)
QUEUED
redis> decrby monery 100
QUEUED
redis> exec
(nil) #返回nil说明监视的tiket已经改变了,事务就取消了