事务的特性和隔离级别

事务的四大特性

数据库事务特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabiliy),简称为ACID原则。

  • 原子性:组成一个事务的多个数据库操作是一个不可分割的原子单元,只有所有操作都成功,整个事务才会提交。任何一个操作失败,已经执行的任何操作都必须侧小,让数据库返回初始状态。
  • 一致性:事务操作成功后,数据库所处的状态和他的业务规则是一致的。既数据不会被破坏。如A转账100元给B,不管操作算法成功,A和B的账号总额是不变的。
  • 隔离性:在并发数据操作时,不同事务拥有各自的数据空间,它们的操作不会对彼此产生干扰。
  • 持久性:一旦事务提交成功,事务中的所有操作都必须持久化到数据库中。

现在我们先来看一下事务中的隔离性中的隔离级别,要搞清楚事务的隔离级别之前,我们先要明白几个概念

关于事务的几个概念(并发事务带来的问题)

在典型的应用程序中,多个事务是并发运行的,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发是必须的,所有可能会导致一下问题。

脏读

所谓脏读就是一个事务读取到了另一个事务未提交的数据,当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是 还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可 能是不正确的。

不可重复读

指在一个事务内多次读取同一个数据,读取到的数据不一样的情况。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

幻读

幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据。在随后的查询中,第一个事务(T1)就会发现多了一些原表不存在的记录,就好像发生了幻觉一样,所以称为幻读。

丢失修改

指在一个事务中读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了该数据。这样第一个事务内的修改结构就被丢失,因此称为丢失修改。
例如:事务T1读取表中的数据A=20,事务T2也读取A=20,事务T1修改A-=1;事务2也修改A-=1.最终结果A=19,事务T1的修改被丢失。

不可重复读和幻读的区别

不可重复读的重点是修改比如多次读取一条记录发现其中某些列的值被修改,幻读的重点再与新增或者删除比如多次读取一条句发现记录增多或减少了。

下面以MYSQL数据库来分析四种隔离级别

第一种隔离级别:Read uncommitted(读未提交)

  读未提交顾名思义,一个事务读取到了另一个未提交的事务,如果一个事务已经开始写操作,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。这样就避免了丢失修改,却可能出现脏读。

  • 解决了丢失修改,但还是可能会出现脏读

第二种隔离级别:Read committed(读提交)

  读提交顾名思义,一个事务要等另一个事务提交之后才能读取数据,一个事务已经开始写数据,那么不允许其他事务对该这个数据进行访问和修改,如果是一个读事务,则允许其他事务读写,该隔离级别避免了脏读,但是可能出现不可重复读。事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。

  • 提交解决了丢失修改和脏读的问题

第三种隔离级别:Repeatable read(可重复读取)

  可重复读(REPEATABLE READ)是MySQL的默认隔离级别,具体是指在同一事务中多次读取的数据是一致的。
  既指在一个事务内,多次读同一个数据,在这个事务还没结束时,其他事务不能修改该数据,这样就可以保证在同一个事务内两次读到的数据是一样的,因此称为是可重复读隔离级别,读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务(包括了读写),这样避免了丢失修改、不可重复读和脏读,但是有时可能会出现幻读。

  • 避免了丢失修改、不可重复读和脏读,但是有时可能会出现幻读

第四种隔离级别:Serializable(可序化)

  Serializable最高的隔离级别,完全服从ACID的隔离级别。可序化要求事务只能一个接着一个地执行,不能并发执行。像Serializeble这样的级别,如果仅仅通过“行级锁”是无法实现序列化的,它是以锁表的形式来使得其他线程在外面进行等待的。

  • 解决了丢失修改、脏读、不可重复读、幻读

总结

请添加图片描述

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

  在MYSQL数据库中,支持上面四种隔离级别,默认的为Repeatable read(可重复读)在Oracle中有三种隔离级别,Read committed(读已提交),Serializeble(串行化),Read only(只读)。

注意

这里需要注意的是:与 SQL 标准不同的地方在于 InnoDB 存储引擎在 REPEATABLE-READ(可重复读) 事务隔离级别下使用的是Next-Key Lock 锁算法,因此可以避免幻读的产生,这与其他数据库系统(如 SQL Server) 是不同的。所以说InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-
READ(可重复读
) 已经可以完全保证事务的隔离性要求,完全服从ACID原则,即达到了 SQL标准的 SERIALIZABLE(可串行化) 隔离级别。
由于隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是READ-COMMITTED(读取提交内容) ,但是你要知道的是InnoDB 存储引擎默认使用 REPEATABLE-READ(可重复读) 。InnoDB 存储引擎在 分布式事务 的情况下一般会用到 SERIALIZABLE(可串行化) 隔离级别。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值