咱们都晓得,如果要实现事务,须要整体保障 ACID(A- 原子性 |C- 持久性 |I- 隔离性 |D- 一致性),其中一致性是指标,原子性、持久性和隔离性都是伎俩,所以这里比照一下 MySQL 和 Redis 在事务实现上的区别,当然严格意义上来说,Redis 因为不满足原子性,不能算真正意义上实现了事务。
原子性
MySQL – 原子性
MySQL 的原子性是通过 undolog 保障的,undolog 是 MySQL 的 回滚 日志,保留的是数据的历史版本,通过历史版本让数据在任何时候都能够回滚到某一个事务开始之前的状态,所以如果事务执行失败了,能够通过 undolog 来保障到原子性。
Redis – 原子性
Redis 没有实现原子性,Redis 的官网文档是这么解释的,所以严格意义上来说,Redis 没有实现事务,因为不能回滚。
It’s important to note that even when a command fails, all the other commands in the queue are processed – Redis will not stop the processing of commands.
持久性
MySQL – 持久性
MySQL 的持久性是通过 redolog 保障的,redolog 是 MySQL 的 前滚 日志,记录数据批改的操作日志,通过操作日志能够保障数据库的数据不失落。
Redis – 持久性
Redis 严格意义上来说,也没有保障到持久性,这是因为它的长久化策略中不论是 RDB 还是 AOF 都是异步执行的,这样还是有可能会造成数据失落。
不过 MySQL 除非应用 双 1
的配置,也就是 sync_binlog 和 innodb_flush_log_at_trx_commit 的配置都是 1,否则也是不满足持久性的;因为如果主机产生异样重启 / 掉电,还是有可能会造成数据失落。所以这里能够认为 Redis 局部实现了持久性。
隔离性
MySQL – 隔离性
MySQL 外面定义了四种规范的隔离级别,通过 MVCC(Multi-Version Concurrency Control,多版本并发管制) 来实现个不同隔离级别的隔离,简略来说,通过数据的版本来控制数据的可见性。
读未提交 – Read Uncommitted
可能会读到其余事务未提交的数据,也就是 脏读
。
读已提交 – Read Committed
读取的数据可能会前后不统一的状况,因为读取的数据可能在事务执行的过程中被批改了。
可反复读 – Repeatable Read
事务一旦开始,事务过程中读取的数据就不能被批改。
然而仍然可能会产生 幻读
,因为可反复读尽管爱护了读取的数据,然而其余数据插入后仍然可能满足以后的查问条件,造成 幻读
。
序列化 – Serializable
零碎中的所有事务都串行执行。尽管能够防止所有数据不统一的状况,然而性能降落显著,个别不倡议应用。
Redis – 隔离性
Redis 的事务在执行的过程中,就不会解决其它命令,而是等所有命令都执行完后,再解决其它命令。所以只有执行了 multi,就会阻塞其余操作。因而 Redis 事务是满足隔离性的。
总结
最初咱们能够用一个表格来总结 Redis 和 MySQL 在事务实现上的区别。
MySQL | Redis | |
---|---|---|
A – 原子性 | undo log | ❌ |
C – 持久性 | redo log | RDB + AOF |
I – 隔离性 | MVVC | 命令单过程 + 单线程执行 |
本文亦通过 NoOne’s Blog 发表,更多分享请关注公众号 NoOneNoOne