事务4大特性,一致性具体指什么?这4个特性mysql如何保证实现的?
事务的四大特性
原子性:事务由一系列动作组成,整个事务的所有操作,要么全部完成,要么全部不完成
一致性:一旦事务完成,在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏
隔离性:隔离状态执行事务,事务与事务之间互不影响各自的操作和执行
持久性:在事务完成以后,该事务对数据库所作的更改操作便持久的保存在数据库之中,而不是临时的,也不会回滚
Mysql怎么保证一致性的?
从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。
但是,如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,你在转账的例子中,你的代码里故意不给B账户加钱,那一致性还是无法保证。因此,还必须从应用层角度考虑。
从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!
Mysql怎么保证原子性的?
是利用Innodb的undo log。 undo log名为回滚日志,是实现原子性的关键,当事务回滚时能够撤销所有已经成功执行的sql语句,他需要记录你要回滚的相应日志信息
Mysql怎么保证持久性的?
是利用Innodb的redo log。
采用redo log的好处? 其实好处就是将redo log进行刷盘比对数据页刷盘效率高,具体表现如下
redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。
redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快。
Mysql怎么保证隔离性的?
利用的是锁和MVCC机制。
MVCC,即多版本并发控制(Multi Version Concurrency Control),一个行记录数据有多个版本对快照数据,这些快照数据在undo log中。
如果一个事务读取的行正在做DELELE或者UPDATE操作,读取操作不会等行上的锁释放,而是读取该行的快照版本。
在事务隔离级别为读已提交(Read Commited)时,一个事务能够读到另一个事务已经提交的数据,是不满足隔离性的。但是当事务隔离级别为可重复读(Repeateable Read)中,是满足隔离性的。
事务隔离级别,4个隔离级别分别有什么并发问题?
未提交读:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
已提交读:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
可重复读:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
串行化:最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
Mysql默认隔离级别?如何保证并发安全?
MySql默认采用可重复读
MySql存储引擎使用的InnoDB,InnoDB支持行级锁和表级锁,默认使用的是行级锁,InnoDB的行级锁有两种:
共享锁:只允许一个事务去读一行,阻止其他事务获取相同数据集的排他锁
排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的共享锁和排他锁<