MySQL 和 Redis 事务的区别
redis 事务不支持原子性和持久性,并且 mysql 事务与 redis 事务的实现原理不同
事务的四大特性
ACID,事务的四大特性缩写:原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolaction)、持久性 (Durability)
1.原子性
一个事务内所有操作就是最小操作单元,要么全部成功,要么全部失败
2.一致性
应用系统从一个正确的状态到另一个正确的状态
一个事务可以封装状态改变 (除非它是一个只读的),事务必须保证系统处于一致状态,不管在任何给定的时间并发事务有多少
数据库的 “一致性” 从底层来说,是一组约束。这组约束可以是约束条件、可以是触发器等,也可以是它们的组合。从更高的层面来说,“一致性” 是一种目的,即保持数据库与真实世界之间的正确映射。此时,需要靠各种锁来达成 “一致性”
3.隔离性
事务可以有多个原子并发执行,但事务之间是互不干扰的;一个事务所做的修改在最终提交之前,对其他事务是不可见的
4.持久性
当一个事物提交之后,数据库状态永远的发生了改变,即这个事物只要提交了,哪怕提交后宕机,他也确确实实的提交了,不会出现因为刚刚宕机了而让提交不生效,是要事物提交,他就像洗不掉的纹身,永远的固化了
命令行执行事务的命令
Mysql
- Begin: 显示开启一个事务
- Commit: 提交事务,将数据库进行所有修改变成永久性
- Rollback: 结束事务,并撤销现在正在进行的为提交修改
mysql 默认会开启一个事务,且缺省设置自动提交,即每成功执行sql,一个事务就会马上 commit,不能 rollback
用Begin、Rollback、commit显式开启并控制一个 新的 Transaction
执行命令 set autocommit=0,用来禁止当前会话自动commit,控制 默认开启的事务
Redis
- Multi:标记事务的开始
- Exec:执行事务的 commands 队列
- Discard:结束事务,并清除 commands 队列
redis 默认不开启事务,即command会立即执行,而不会排队,并不支持rollback
用multi、exec、discard,显式开启并控制一个Transaction
实现原理
Mysql
mysql 是基于 undo/redo 日志实现事务
- undo 记录修改前状态,rollback 基于 undo 日志实现
- redo 记录修改后状态,commit 基于 redo 日志实现
Redis
redis 是基于 commands 队列实现事务
- 没有开启事务,command将会被立即执行并返回执行结果,并且直接写入磁盘
- 开启事务,command不会被立即执行,而是排入队列,并返回排队状态(具体依赖于客户端(例如:spring-data-redis)自身实现)
调用 exec
从会执行 commands 队列
Redis 事务并不支持 Rollback,redis 命令在事务执行时失败,仍会继续执行剩下命令而不是 Rollback (事务回滚)
Redis 事务中的两大命令错误:
- 一个命令可能排队失败,所以在 EXEC 调用之前可能会出错。例如,该命令可能在语法上是错误的(参数数量错误,命令名称错误,…),或者可能存在一些紧急情况,例如内存不足情况(如果使用该 maxmemory 指令将服务器配置为具有内存限制)
- 调用后 命令可能会失败 EXEC,例如,因为我们对具有错误值的键执行了操作(例如对字符串值调用列表操作)
从 Redis 2.6.5 开始,服务器会在命令累积过程中检测到错误。然后它将拒绝执行在 期间返回错误 EXEC 的事务,丢弃该事务
Redis < 2.6.5 的注意事项:在 Redis 2.6.5 之前,客户端需要 EXEC 通过检查排队命令的返回值来检测之前发生的错误:如果命令以 QUEUED 回复,则表示正确排队,否则 Redis 返回错误。如果在排队命令时出现错误,大多数客户端将中止并丢弃事务。否则,如果客户端选择继续事务,则该 EXEC 命令将成功执行所有排队的命令,而不管先前的错误如何
评论区