您的位置:首页 > 数据库

数据库-事务的ACID和隔离级别

2018-03-05 17:22 253 查看
写在前面:
    数据库是面试的一大重点,在上一篇博客中,我们已经总结了数据库的三大范式,在这篇博客中,将会总结另一个总会被问到的问题--事务的ACID和事务隔离级别。

    事务(Transaction):

    在计算机语言中,一般指访问并更新数据库中的一个程序执行单元。 事务具有的四个特点,称为ACID。在数据库的并发访问中,为了保证数据的读取正确性,设置的事务的隔离级别。

    事务的ACID:

A:(Atomicity) 原子性,一个事务是一个不可分割的单位,事务中的所有操作,要么全完成,要么全不完成,任何一个操作的失败,都会回滚到事务执行之前的状态。
C:Consistentcy 事务结束后,系统状态是一致的。即,在并发操作时,系统的状态也要和串行执行事务时一样。
例如: ABCDE五个账户,每个账户有100元,共计500元,A给B转账10元,B给C转账5元,C给D转账5元,D给E转账10元,E给A转账10元,当转账同时进行,模拟并发操作数据库,最后5个账户的总额度仍旧应该是500元。

I:Isolation 隔离性,并发执行的事务之间,无法看到彼此的系统状态。
D:Durability 持久性,在事务完成后,事务对数据库的操作会被持久保存在数据库中,不会被回滚。

    多事务访问产生的问题:

    (1)脏读(Dirty Read):A读取B事务尚未提交的事务,并修改了B的数据,然后B对事务执行回滚,那么A读取到的数据为脏读。

时间事务A事务B
T1 事务开始
T2事务开始 
T3 查询账户余额=500元
T4 账户+500元
T5A查询到账户数据为1000元(脏读) 
T6A取出200元 
T7 回滚事务
T8 提交事务
    (2)不可重复读(Unrepeatable Read):事务A读取数据,然后事务B对事务A的数据进行了修改,此后,事务A再次读取数据,这时为不可重复读,最后A提交事务。所以在A的一次事务中,两次读取到的数据不一致。
时间事务A事务B
T1事务开始 
T2 事务开始
T3读取账户余额=1000元 
T4 读取账户余额=1000元
T5 账户+500元
T6 提交事务
T7读取账户余额=1500元(不可重复读) 
    (3)幻读(Phantom Read):事务A查询数据,查询一切符合查询条件的行,这时B新增加一个行数据,A事务再次查询时,发现与第一次查询相比,新增加了一行。
时间事务A事务B
T1 开始事务
T2开始事务 
T3查询所有符合条件账户=100的行 
T4 新增加一个账户行,并且账户=100
T5 提交事务
T6再次查询所有符合条件账户=100的行 
    在看过了上面数据并发访问时可能产生的问题,在有些场景下可能是允许的,但是有些场景下可能就是致命的,数据库通常会通过锁机制来解决数据并发访问问题,按锁定对象不同可以分为表级锁和行级锁;按并发事务锁定关系可以分为共享锁和独占锁。
    直接使用锁是非常麻烦的,为此数据库为用户提供了自动锁机制,只要用户指定会话的事务隔离级别,数据库就会通过分析SQL语句然后为事务访问的资源加上合适的锁。

隔离级别

    事务的隔离级别有4个,由低到高分别为:Read uncommited ,Read commited ,Reapeatable Read ,Serializable,他们分别可以解决以上在并发访问数据库时所产生的脏读,不可重复读,幻读等线程安全问题。✔️表示允许,❌表示不允许
隔离级别脏读不可重复读幻读
Read uncommited✔️✔️✔️
Read commited✔️✔️
Reapeatable Read✔️
Serializable
    注:Serializable是最高的隔离级别,可以全部避免脏读,不可重复读,幻读等问题,但效率偏低,花费较大,一般不使用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACID 隔离级别