一、数据库的隔离级别:

        1.读未提交(Read uncommitted);

        2.读已提交(Read committed);

        3.可重复读(Repeatable read),数据库默认开启;

        4.串行化(Serializable );

二、首先用通俗的语言介绍以下事务的特性(ACID):

        (1).原子性(Atomicity):原子性是指一个事务中的操作,要么全部成功,要么全部失败,如果失败,就回滚到事务开始前的状态。

        (2).一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。那转账举栗子,A账户和B账户之间相互转账,无论如何操作,A、B账户的总金额都必须是不变的。

        (3).隔离性(Isolation):隔离性是当多个用户 并发的 访问数据库时,如果操作同一张表,数据库则为每一个用户都开启一个事务,且事务之间互不干扰,也就是说事务之间的并发是隔离的。再举个栗子,现有两个并发的事务T1和T2,T1要么在T2开始前执行,要么在T2结束后执行,如果T1先执行, 那T2就在T1结束后在执行。关于数据的隔离性级别,将在后文讲到。

        (4).持久性(Durability):持久性就是指如果事务一旦被提交,数据库中数据的改变就是永久性的,即使断电或者宕机的情况下,也不会丢失提交的事务操作。

三、如果不考虑隔离性,会发生什么事呢?

(1).脏读:

        脏读是指一个事务在处理数据的过程中,读取到另一个未提交事务的数据。

(2).不可重复读:

        不可重复读是指对于数据库中的某个数据,一个事务范围内的多次查询却返回了不同的结果,这是由于在查询过程中,数据被另外一个事务修改并提交了。

(3).幻读

        幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。

解决不可重复读的方法是 锁行,解决幻读的方式是 锁表。

四、四种隔离级别解决了上述问题

        1.读未提交(Read uncommitted):这种事务隔离级别下,select语句不加锁。

此时,可能读取到不一致的数据,即“读脏 ”。这是并发最高,一致性最差的隔离级别。

        2.读已提交(Read committed):可避免 脏读 的发生。在互联网大数据量,高并发量的场景下,几乎 不会使用 上述两种隔离级别。

        3.可重复读(Repeatable read):MySql默认隔离级别。可避免 脏读 、不可重复读 的发生。

        4.串行化(Serializable ):可避免 脏读、不可重复读、幻读 的发生。

        以上四种隔离级别最高的是串行化级别,最低的是读未提交级别,当然级别越高,执行效率就越低。像串行化这样的级别,就是以锁表的方式(类似于Java多线程中的锁)使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。在MySQL数据库中默认的隔离级别为可重复读。

        在MySQL数据库中,支持上面四种隔离级别,默认为可重复读;而在 Oracle数据库 中,只支持串行化级别和读已提交,其中默认的为读已提交级别。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐