MySql
非关系型数据库--稳定--开源
事务
逻辑上的一组操作,要么都执行,要么都不执行。
事务的ACID:
- 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行;
- 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态,一致状态的含义是数据库中的数据应满足完整性约束。(应该类似于物理上的能量守恒吧,能量之间互相转换,不会凭空消失与产生);
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
- 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中,宕机也可以恢复。
事务并发所产生的的问题
- 脏读(Dirty read):A事务读取了B事务未提交的数据,A事务读到的数据就是脏数据。
- 丢失修改(Lost to modify):A事务与B事务读取同一数据,A事务先对该数据进行修改,B后再进行修改,B修改的结果会对A做的修改进行覆盖,导致A修改的数据丢失。
- 不可重复读(Unrepeatableread):A事务开启,在此事务内多次访问某数据,期间B事务对该数据进行了修改,在A事务内两次独读到的该数据可能会不一致。
- 幻读(Phantom read):A事务读取了部分数据,B事务又插入了一些数据,A事务再次读取时,会发现多了一些数据,如同产生幻觉。
不可重复度侧重点在于修改,幻读在于删除或者插入。
事务的隔离级别
- READ-UNCOMMITTED(读未提交的):最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。
- READ-COMMITTED(读已提交的):允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。
- REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(串行化):最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。
隔离级别越高,效率越低。
MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读)。
通过SELECT @@tx_isolation;
命令来查看:
与 SQL 标准不同的地方在于InnoDB 存储引擎在 REPEATABLE-READ(可重读)事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server)是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重读) 已经可以完全保证事务的隔离性要求,即达到了 SQL标准的SERIALIZABLE(可串行化)隔离级别。
因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容):,但是你要知道的是InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读)并不会有任何性能损失。
InnoDB 存储引擎在 分布式事务 的情况下一般会用到SERIALIZABLE(可串行化)隔离级别。