Redis 事务
关系型数据中的事务都是原子性的,而redis 的事务是非原子性的。
Redis事务相关命令:
- MULTI :开启事务,redis会将后续的命令逐个放入队列中,然后使用EXEC命令来原子化执行这个命令系列。
- EXEC:执行事务中的所有操作命令。
- DISCARD:取消事务,放弃执行事务块中的所有命令。
- WATCH:监视一个或多个key,如果事务在执行前,这个key(或多个key)被其他命令修改,则事务被中断,不会执行事务中的任何命令。
- UNWATCH:取消WATCH对所有key的监视。
mysql 事务和 redis事务对比
一致性(Consistency) | 隔离性(Isolation) | 持久性(Durability) | 原子性(Atomicity) | |
mysql | 支持 | 支持 | 支持 | 支持 |
redis | 支持 | 支持 | 不支持 | 不支持 |
原子性(Atomicity)
一个事物内所有操作,要么全部成功,要么全部失败。这是最基本的特性,保证了因为一些其他因素导致数据库异常,或者宕机。
一致性(Consistency)
一致性是指数据处于一种语义上的有意义且正确的状态。一致性是对数据可见性的约束,保证在一个事务中的多次操作的数据中间状态对其他事务不可见的。因为这些中间状态,是一个过渡状态,与事务的开始状态和事务的结束状态是不一致的。
原子性和一致性的的侧重点不同:原子性关注状态,要么全部成功,要么全部失败,不存在部分成功的状态。而一致性关注数据的可见性,中间状态的数据对外部不可见,只有最初状态和最终状态的数据对外可见
Table: Account Columns: Name(string), Balance(int) 约束条件:Balance >= 0 执行下面一个事务(A,B的初始余额均为1000,A给B转账1200) 1. 往表Account插入数据(A,1000) 2. 往表Account插入数据 (B,1000) 3. A给B转账1200,更新A的余额为-200,(A,-200) 4. B的余额增加1200,更新B的余额为2200(B,2200) 注意,这里增加了约束条件Balance > 0, 上面的这个 transaction违反了规则Balance>=0,那么这个事务数据库认为它是非法的,不满足一致性的要求,所以数据库执行这个事务会失败。
隔离性
事物的隔离性,基于原子性和一致性,因为事物是原子化,量子化的,所以,事物可以有多个原子包的形式并发执行,但是,每个事物互不干扰。
但是,由于多个事物可能操作同一个资源,不同的事物为了保证隔离性,会有很多锁方案,当然这是数据库的实现
持久性
持久性,当一个事物提交之后,数据库状态永远的发生了改变,即这个事物只要提交了,哪怕提交后宕机,他也确确实实的提交了,不会出现因为刚刚宕机了而让提交不生效
来个事务小实战吧
执行执行一组事务命令
其中一条命令执行错误,后续的命令还是会继续执行。比如对string类型进行incr
操作,并没有语法错误,但是会产生一个异常
基于WATCH对于事务作中断测试
客户端<1>
客户端<2>
总结:
1、当监控的key被其中一个事务修改后,那么另一个事务的执行将会被打断
2、n个事务事务开启,谁先exec谁成功,后面的exec会被打断