数据库的ACID特性及事物隔离级别-科普入门级别
数据库ACID特性
(1)原子性(Actomicity):对数据的操作,要么全都执行,要么全都不执行,整个事物视为一个整体
(2)一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的
(3)隔离性(Isolation):数据库系统提供一定的隔离机制,确保事务不受其他事物的影响,同时事物的中间状态对外不可见
(4)持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持
事物隔离级别
事务是由一组SQL语句组成的逻辑处理单元,事务具有4属性,通常称为事务的ACID属性。
查询当前mysql事物隔离级别
1 | select @@tx_isolation; |
第一级别:Read Uncommitted(未提交读)
1 | set tx_isolation='READ-UNCOMMITTED'; |
(1)当前事物可以看到其他事务未提交事务的数据,造成脏读
(2)本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少,但是副作用又较大
第二级别:Read Committed(已提交读)
1 | set tx_isolation='READ-COMMITTED'; |
(1)当前事物可以读取到其他事物已经提交的数据,造成不可重复读(Non repeatable Read)
(2)大多数数据库系统的默认隔离级别(但不是MySQL默认的)
(3)不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。
(4)导致这种情况的原因可能有:
a、有一个交叉的事务有新的commit,导致了数据的改变;
b、一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit
第三级别:Repeatable Read(可重读)
1 | set tx_isolation='REPEATABLE-READ'; |
(1)MySQL的默认事务隔离级别
(2)同一事务的多个实例在并发读取数据时,会看到同样的数据行
(3)此级别可能出现的问题–幻读(Phantom Read):
当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影”
(4)InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,MultiVersion Concurrency Control)机制解决了该问题
第4级别:Serializable(可串行化),完美,但是并发低
1 | set tx_isolation='SERIALIZABLE'; |
(1)这是最高的隔离级别,使读写操作串行化,一般不用
(2)它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。它在每个读的数据行上加上共享锁。
(3)在这个级别,可能导致大量的超时现象和锁竞争
数据库实现事物隔离级别的方式
(1)对其加锁,阻止其他事务对数据进行修改
(2)MutiVersion Concurrency Control,简称MVCC或MCC多版本控制,通过一定机制生成一个数据请求时间点的一致性数据快照(Snapshot),
并用这个快照来提供一定级别的一致性读取
在MVCC并发控制中,读操作可以分成快照读 (snapshot read)与当前读 (current read)。
快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。
当前读,读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
InnoDB就是基于多版本控制的引擎
并发事务带来的问题
相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,但并发事务处理也会带来一些问题,主要包括以下几种情况:
(1)更新丢失(Lost Update):当多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,多个事物同时更新数据,就会发生丢失更新问题 -> 乐观锁
(2)脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”的数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做“脏读”。
(3)不可重复读(Non-Repeatable Reads):一个事务在读取某些数据已经发生了改变、或某些记录已经被删除了!这种现象叫做“不可重复读”。
(4)幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。