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

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

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

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

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

什么是事务的隔离性(Isolation)呢?

       隔离性是指,多个用户的并发事务访问同一个数据库时,一个用户的事务不应该被其他用户的事务干扰,多个并发事务之间要相互隔离。

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

1.脏读:

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

 2.不可重复读:

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

       不可重复读和脏读的区别是,脏读读取到的是一个未提交的数据,而不可重复读读取到的是另一个事务提交的数据。

       而不可重复读在一些情况也并不影响数据的正确性,比如需要多次查询的数据也是要以最后一次查询到的数据为主。

3.幻读

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

       幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

       不可重复读和幻读是初学者不易分清的概念,总的来说,解决不可重复读的方法是 锁行,解决幻读的方式是 锁表。

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

1.读未提交(Read uncommitted):

       这种事务隔离级别下,select语句不加锁。

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

2.读已提交(Read committed):

       可避免 脏读 的发生。

       在互联网大数据量,高并发量的场景下,几乎 不会使用 上述两种隔离级别。

3.可重复读(Repeatable read):

       MySql默认隔离级别。

       可避免 脏读 、不可重复读 的发生。

4.串行化(Serializable ):

       可避免 脏读、不可重复读、幻读 的发生。

       以上四种隔离级别最高的是 Serializable 级别,最低的是 Read uncommitted 级别,当然级别越高,执行效率就越低。像 Serializable 这样的级别,就是以 锁表 的方式,使得其他的线程只能在锁外等待,所以平时选用何种隔离级别应该根据实际情况。SQL Server默认的隔离级别为rcommitted,MySQL默认的隔离级别为Repeatable read, Oracle默认隔离级别为Read committed。

  SQL Server和MySQL数据库支持上面四种隔离级别,而 Oracle数据库只支持Serializable (串行化) 级别和 Read committed (读已提交) 这两种级别。  

本文转自:https://blog.csdn.net/u010960184/article/details/82557978,并进行部分修改

Logo

华为云1024程序员节送福利,参与活动赢单人4000元礼包,更有热门技术干货免费学习

更多推荐