美文网首页
数据库的事务隔离级别

数据库的事务隔离级别

作者: _52Hertz | 来源:发表于2020-02-29 15:54 被阅读0次

    事物的特性-ACID

    1. A-原子性(Atomicity)

    原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

    1. C-一致性(Consistency)

    事务前后数据的完整性必须保持一致。

    1. I-隔离性(Isolation)

    事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

    1. D-持久性(Durability)

    持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

    事物的隔离性

    概念已述

    没有事物隔离会产生的情况
    1. 场景一(脏读)

    事务A访问了数据库,往数据库里添加新人的名字,但是没有提交事务。

    insert into User values (4, '张三');

    这时,来了另一个事务B,他要查询所有人的名字。

    select Name from User;

    这时,如果没有事务之间没有有效隔离,那么事务B返回的结果中就会出现“张三”的名字。这就是“脏读(dirty read)”。

    1. 场景二(不可重复读)

    事务A访问了数据库,查看ID是1的人的名字

    select Name from User where ID = 1;

    这时,来了另一个事务B,更新ID是1的人的名字然后提交了事务。

    update User set Name = '李四' where ID = 1;

    接着,事务A还想再看看ID是1的人的名字,于是又执行了

    select Name from User where ID = 1;

    此时发现两次读取的数据不一致,这就是不可重复读(unrepeatable read)。

    1. 场景三(幻读)

    事务A访问了数据库,查看数据库的所有人,于是执行了

    select * from User;

    这时候,事务B来了,往数据库添加新人。

    insert into User values(4, '王五');

    这时候,事务A重新查看所有的人,于是又执行了。

    select * from User;

    事物A就很蒙,发现两次读取的人数不一样,这种情况就叫“幻读(phantom problem)”。

    事物的隔离级别

    所以为了防止出现脏读,不可重复读,幻读的情况,我们需要根据情形为数据库设立不同的隔离级别。

    读未提交(Read Uncommitted)

    读未提交,顾名思义,就是可以读到未提交的内容。

    因此,在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差
    的,可能会产生“脏读”、“不可重复读”、“幻读”。

    如无特殊情况,基本是不会使用这种隔离级别的。

    读提交(Read Committed)

    读提交,顾名思义,就是只能读到已经提交了的内容。

    这是各种系统中最常用的一种隔离级别,也是SQL Server和Oracle的默认隔离级别。这种隔离级别能够有效的避免脏读,但除非在查询中显示的加锁,如:

    select * from T where ID=2 lock in share mode;

    select * from T where ID=2 for update;

    不然,普通的查询是不会加锁的。

    那为什么“读提交”同“读未提交”一样,都没有查询加锁,但是却能够避免脏读呢?

    这就要说道另一个机制“快照(snapshot)”,而这种既能保证一致性又不加锁的读也被称为“快照读(Snapshot Read)”

    假设没有“快照读”,那么当一个更新的事务没有提交时,另一个对更新数据进行查询的事务会因为无法查询而被阻塞,这种情况下,并发能力就相当的差。

    而“快照读”就可以完成高并发的查询,不过,“读提交”只能避免“脏读”,并不能避免“不可重复读”和“幻读”。

    可重复读(Repeated Read)

    可重复读,顾名思义,就是专门针对“不可重复读”这种情况而制定的隔离级别,自然,它就可以有效的避免“不可重复读”。而它也是MySql的默认隔离级别。

    在这个级别下,普通的查询同样是使用的“快照读”,但是,和“读提交”不同的是,当事务启动时,就不允许 进行“修改操作(Update)”了,而“不可重复读”恰恰是因为两次读取之间进行了数据的修改,因此,“可重复读”能够有效的避免“不可重复读”,但却避免不了“幻读”,因为幻读是由于“插入或者删除操作(Insert or Delete)”而产生的。

    串行化(Serializable)

    这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。

    这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免,但是执行效率奇差,性能开销也最大,所以基本没人会用。

    相关文章

      网友评论

          本文标题:数据库的事务隔离级别

          本文链接:https://www.haomeiwen.com/subject/nbwphhtx.html