事务ACID和隔离等级

事务ACID理解

谈到事务一般都是以下四点

原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
一致性(Consistency)
事务前后数据的完整性必须保持一致。
隔离性(Isolation)
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
持久性(Durability)
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

举个简单的例子理解以上四点

原子性**(Atomicity)**

拿银行转钱这个事情来讲

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jT9OXyOH-1645264080480)(面试文档.assets/image-20220219170714743.png)]

A要从银行给B转钱,这个事务就包括两个动作,一个是A给银行钱,一个是B从银行收到钱。这两个动作要么全部成功要么全部失败,这就叫做原子性。

一致性(Consistency)

保证操作前后的一致性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-glGF8G6C-1645264080482)(面试文档.assets/image-20220219170744281.png)]

就继续拿这个举例子,A转给了B200,所以A从1000块变成了800块,而B收到了200块,所以从100块变成了300块。这就叫做一致性。

持久性(Durability)

表示事务结束后的数据不随着外界原因导致数据丢失。

如果事务在提交前因为某些原因终止,那么当数据库重启时,我们会发现A还是1000块,B还是100块。

如果事务在提交后因为某些原因终止,那么当数据库重启时,我们会发现A还是800块,B还是300块。

隔离性(Isolation)

针对多个用户同时操作,主要是排除其他事务对本次事务的影响

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KKxtRQ5w-1645264080483)(面试文档.assets/image-20220219171514708.png)]

在这里他是有两个事务的,一个是A给B转钱,一个是C给B转钱。

为了保证隔离性,我们一定是有个相对的执行顺序,类似于我们解决并发加锁的一个过程,要么A给B转钱后C再给B转钱,要么C给B转钱后A再给B转钱。

ACID是靠什么保证的?

原子性由undolog日志来保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql

一致性是由其他三大特性保证,程序代码要保证业务上的一致性

隔离性是由MVCC来保证

持久性由redolog来保证,mysql修改数据的时候会在redolog中记录一份日志数据,就算数据没有保存成功,只要日志保存成功了,数据仍然不会丢失

事务的隔离级别

脏读:

指一个事务读取了另外一个事务未提交的数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QS1MGYMz-1645264080483)(面试文档.assets/image-20220219171514708.png)]

正常的过程应该如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nXHJ8fy-1645264080484)(面试文档.assets/image-20220219173038846.png)]

但是这个时候,c在A和B转钱这个事务还未完成的时候我就读取了B的数值,也就是在第三步前拿到了B的数值,从而使结果变成了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YarmhE9a-1645264080484)(面试文档.assets/image-20220219173417659.png)]

不可重复读:

一个事务读到另一个事务修改后并提交的数据(update)。在同一个事务中,对于同一组数据读取到的结果不一致。比如,事务B 在 事务A 提交前读到的结果,和在 事务A 提交后读到的结果可能不同。不可重复读出现的原因就是由于事务并发修改记录而导致的。

举例说明:

依旧是上面银行转钱问题,就是A给B转钱的过程中,银行发现C在这个过程中完成了转钱的过程,这个时候就就出现了分歧,我不知道用C转钱前的结果还是转钱后的结果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdyTj2EV-1645264080485)(面试文档.assets/image-20220219171514708.png)]

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取数量总量不一致。(一般是行影响,如下图所示:多了一行)

举例说明:
现在有一个动作是关于操作列表的,起初一个列表只有三行,结果在第一个事务进行的过程中,突然有别的事务插入了一行数据,导致第一个事务后面读取过程中发现突然多了一行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Om64Epni-1645264080486)(面试文档.assets/image-20220219174544757.png)]

四种隔离级别设置

隔离级别 有四种,分别是:读未提交、读已提交、可重复读、序列化。

  • 读未提交: Read Uncommitted,顾名思义,就是一个事务可以读取另一个未提交事务的数据。最低级别,它存在4个常见问题(脏读、不可重复读、幻读、丢失更新)。
  • 读已提交: Read Committed,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。 它解决了脏读问题,存在3个常见问题(不可重复读、幻读、丢失更新)。
  • 可重复读: Repeatable Read,就是在开始读取数据(事务开启)时,不再允许修改操作 。它解决了脏读和不可重复读,还存在2个常见问题(幻读、丢失更新)。
  • 序列化: Serializable,序列化,或串行化。就是将每个事务按一定的顺序去执行,它将隔离问题全部解决,但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值