mysql事务隔离级别
mysql的事务
四大特性ACID
原子性:操作要么全部成功,要么全部失败
一致性:事务开始和结束,数据库是完整的,比如转账
隔离性:一个事务不能被其他事务打扰
持久性:事务完成后,将数据持久化保存到数据库中,不会被回滚
事务的实现原理
隔离性:通过加锁(并发控制MVCC/LBCC),出现脏读、不可重复读、幻读问题
原子性和持久性:通过redo log重做日志实现
一致性:通过undo log 回滚日志实现
undo log原理—>备份旧数据
在操作数据库之前,首先将数据备份到一个地方(undo log)。然后进行数据修改,如果出现错误需要回滚,则从undo log中的获取事务开启之前的数据(逻辑上的备份)
redo log原理—>保存最新数据
与undo log相反,redo log记录都是最新的数据备份。在事务提交前,只要将redo log 持久化即可,不需要将数据持久化。系统出现问题,数据没有持久化,但是redo log已经持久化。从redo log中将所有数据恢复到最新的状态(物理上的备份)
事务并发调度出现的问题(并发问题)
- 脏读:两个事务,一个事务读取到了另一个事务未提交的数据
- 不可重复读:一个事务中两次读取的数据内容不一致(说明了数据给修改)
- 幻读:一个事务中两次读取的数据的数量不一致,因为另一个事务是insert/delete操作(其实事务的提交会影响在同一个事务中的重复查询结果)
四种隔离级别解决问题
-
Read Uncommitted(读未提交)
原理:事务A和事务B,事务B可以读取事务A未提交的记录。出现脏读,因为事务A可能回滚操作,导致数据发生变化。 -
Read Committed(读已提交)
原理:事务中只能看到已提交的修改,提交读这种隔离级别保证了读到的任何数据都是提交的数据,避免了脏读,但是不保证事务重新读的时候能读到相同的数据,因为在每次数据读完之后其他事务可以修改刚读到的数据 -
Repeated Read可重复读—>解决脏读和不可重复读(解决幻读,需要加锁)
原理:RR隔离级别保证对读取到的记录加锁(记录锁),同时保证对读取的范围加锁,新的满足查询条件不能插入(间隙锁),因此不存在幻读现象。===>乐观锁(MVCC机制,比较版本号)
标准的RR隔离级别只能保证在同一个事务中多次读取同样记录的结果是一致的,而无法解决幻读问题。(行锁控制) -
Serializable可串行化:解决所有问题
原理:该隔离级别会在读取的每一行数据上都加上锁,降级为基于锁的并发控制,即LBCC(悲观机制)—>行锁升级为表锁来解决幻读
mysql中使用RR隔离解决幻读:
Innodb的幻读解决是—>MVCC机制实现(乐观锁机制),通过AtomicReference来实现,增加系统版本号(计数器),每次事务操作,会比较系统版本号。
MVCC的说明:
一种多版本并发控制机制
MVCC可以大多情况代替行级锁
MVCC是一种后验性的,读不阻塞写,写也不阻塞读,等到提交的时候才检验是否有冲突,由于没有锁,所以读写不会相互阻塞,从而大大提升了并发性能。
MVCC只能在RC和RR两个隔离级别下工作,其他两个不兼容
上一篇: 华为端口隔离技术