JavaGuide笔记
存储引擎InnoDB
在5.7版本中只有InnoDB是事务性存储引擎,也就是只有InnoDB支持事务。
MyISAM 和 InnoDB 的区别
Mysql5.5之前MyISAM是Mysql的默认存储引擎,但是他不支持事务和行级锁,最大的缺陷是崩溃后无法安全恢复。
是否支持行级锁
MyISAM只有表级锁,InnoDB支持行级锁和表级锁,默认为行级锁。
前者一锁就是锁住了整个表。
是否支持事务
MyISAM不提供事务支持
InnoDB提供事务支持,具有提交(commit)和回滚(rollback)事务的能力
是否支持外键
MyISAM不支持 InnoDB支持
是否支持数据库异常崩溃之后的安全恢复
MyISAM不支持,InnoDB支持,数据库重新启动的时候会保证数据库回复到崩溃前的状态,这个过程依赖于redo log(重做日志)
拓展
InnoDB使用redo log(重做日志)保证事务的持久性 使用undo log(回滚日志)保证事务的原子性
InnoDB通过锁机制、mvcc等手段保证事务的隔离性
保证事务的持久性、原子性、隔离性后,一致性才能得到保障
InnoDB存储引擎的锁的算法有三种:
- Record lock:记录锁,单个行记录上的锁
- Gap lock:间隙锁,锁定一个范围,不包括记录本身
- Next-key lock:record+gap临建锁,锁定一个范围,包括记录本身
事务
什么是事务
事务是逻辑上的一组操作,要么执行,要么都不执行
什么是数据库事务
保证对数据库的操作(也就是sql语句)构成一个逻辑上的整体,构成这个逻辑上的整体的这些数据库操作遵循:要么全部执行成功,要么全部不执行。
ACID特性(原子性、一致性、隔离性、持久性)
- 原子性:Atomicity,事务是最小的执行单位,不允许分割。要么全部完成,要么全部不执行
- 一致性:Consistency,执行事务前后,数据保持一致。转账中收钱和转钱人的总额应该是不变的。
- 隔离性:Isolation,并发访问数据库时,一个用户的事务不被其他事务干扰,各并发事务之间数据库独立
- 持久性:Durability,一个事务被提交以后,他对数据库中的数据的改变是持久的,及时数据库发生故障也不应该对其有任何影响。
数据事务的实现原理
InnoDB用redo log(重做日志)保证事务的持久性
undo log(回滚日志)保证事务的原子性
InnoDB通过锁机制、MVCC等保证事务的隔离性(默认支持的隔离级别是REPEATABLE-READ)
保证了事务的持久性、原子性、隔离性后,一致性才能得到保障。
并发事务带来什么问题
多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一个数据进行操作)
- 脏读:一个事务正在访问数据并对数据进行修改,而这个数据还没提交到数据库中,这是另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,另外一个事务读到的这个数据是脏数据。
- 丢失修改:一个事务读取一个数据时,另外一个事务也访问了这个数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就会丢失。事务1读到a = 20,事务2也读到了a = 20,现在两个人都执行a-1,结果是19,有一个的修改丢失了。
- 不可重复读:在一个事务内多次读同一个数据,在这个事务还没有结束的时候,另外一个事务也访问该数据,那么第一个事务的两个读数据之间,由于被第二个事务修改,导致第一个事务两次读到的数据可能不一样。出现了一次事务中两次读到的数据不一样的情况。
- 幻读:一个事务T1读取了几行数据,接着另外一个事务T2插入了一些数据,随后的查询中,第一个事务T1发现多了一些原本不存在的记录。
不可重复读和幻读的区别:
不可重复读的重点是修改,幻读的重点是新增或者删除。
事务隔离级别有哪些
四个隔离级别:
- 读取未提交:最低的隔离级别,允许读取尚未提交的数据变更,可能导致脏读、幻读、不可重复读
- 读取已提交:允许读取事务已经提交的数据吗,可以阻止脏读,但是幻读和不可重复读还是有可能发生
- 可重复读:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,幻读还是有可能发生
- 可串行化:最高的隔离级别,完全服从ACID的隔离级别。所有的事务逐个执行,这样子就完全不可能产生干扰。
InnoDB的默认隔离级别是可重复读