mysql事务隔离级别

事务的安全保障

ACID
原子性(atomicity)、持久性(consistency)、隔离性(isolation)、一致性(durability)。

原子性

当一个事务在执行途中发生错误,我们很难知道哪些更改已经生效,哪些更改没有生效,而如果重试可能会导致数据重复或者数据错误。为了简化这个问题,数据库丢弃或者撤销该事务中迄今为止任何写入,这样做就可以保证没有任何东西在这个过程中被改变,所以可以安全的重试。
中止出错的事务,并撤销该事务进行的所有变更。

一致性

一致性是应用程序的属性,应用程序可以用原子性和隔离性来实现一致性。
如果一个财务系统,账户A转钱到账户B,那么账户A中减少的钱与账户B中增加的钱必须相等。这并不是数据库可以保证的事情,而是应用程序来保证的。

隔离性

同时执行的事务不能互相冒犯。这意味着,每个事务都可以认为它是唯一在整个数据库还是那个运行的事务。数据库确保多个事务提交后,结果与他们按顺序一个接着一个的运行是一样的,尽管实际上他们可能是并发的。
假设两个客户端同时增长一个计数器(当前值为10),每个客户端需要读取计数器的当前值,加1后在写新值。因为发生了两次增长,计数器应该从10增长到12。但是由于两个客户端同时读取,拿到的原值都是10,执行加1操作后都写回了11,出现了数据错误。

持久性

安全的存储数据,而不用担心丢失。
数据库的预写日志或分布式系统的复制可以为持久性做出承诺。

脏读/不可重复读/幻读

事务的隔离,以是否脏读/重复读/幻读为分界线。这里先简要说明一下什么是脏读/重复读/幻读。

脏读

在事务A执行过程中,事务A对数据进行修改,事务B读取了事务A修改后的数据。由于某些原因,事务A并没有完全提交,发生了回滚(rollback)操作,则事务B读取的就是脏数据。

这种读取另一个事务未提交的数据的现象就是脏读。
在这里插入图片描述

不可重复读

事务B读取两次数据,在事务B读取数据的过程中事务A修改了数据,导致事务B在两次读取的数据不一致。
这种同一事务中,前后两次读取数据不一致的现象就是不可重复读。
在这里插入图片描述

幻读

事务B先后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次和前一次查到的行不一致。
幻读和不可重复读类似,但是幻读强调的是集合的增减,而不是单条数据的更新。
在这里插入图片描述

第一类更新丢失

事务A和事务B对同一个数据进行更新,但是事务A由于某种原因事务回滚了,把已经提交的事务B的数据给覆盖了。这种现象叫第一类更新丢失。
在这里插入图片描述

第二类更新丢失

第二类更新丢失和第一类更新丢失有点类似,两个事务对数据进行更新,事务A把事务B的更新覆盖了。这种现象就是第二类更新丢失。
在这里插入图片描述

事务隔离级别

读未提交
读已提交
可重复读
串行化

读未提交

Read Uncommitted,是最低的隔离级别,所有的事务都可以看到其他未提交事务的执行结果。只能防止第一类更新丢失,不能解决脏读、可重复读、幻读,很少应用于实际项目。

读已提交

Read Committed,在该隔离级别下,一个事务的更新操作结果只有在该事务提交之后,另一个事务才可能读取到同一笔数据更新后的结果。可以防止脏读和第一类更新丢失,但是不能解决可重复读和幻读。

可重复读

Repeatable read,mysql默认的隔离级别。在该隔离级别下,一个事务多次读同一个数据,在这个事务还没结束时,其他事务不能访问该数据(包括读写),这样就可以在同一个事务内两次读到的数据是一样的。可以防止脏读、不可重复读、第一类更新丢失、第二类更新丢失的问题。不能防止幻读。

串行化

serializable,最高的隔离级别。他要求事务序列化执行,事务只能一个接着一个执行,不能并发执行。在这个级别,可以解决上面提到的所有并发问题,但是可能导致大量的超时现象和锁竞争,通常不会用这个隔离级别。

其他解决幻读的方法

物化冲突

如果幻读的问题是没有对象可以加锁,也许可以人为的在数据库中引入一个锁对象。

串行化实现

两阶段锁定、共享锁、互斥锁
两阶段锁定实现了最强的隔离级别,即串行化----无论怎么并发写,最终与一个一个顺序发生的结果都是一样的。
两阶段锁定要求:只要没有写入,就允许多个事务同时读同一行。但只要有写入(修改或删除),就独占访问权限。换句话说,写入不仅会阻塞其他写入,也会阻塞读

两阶段锁含义:
第一阶段(只加锁):事务开始前,进程尝试对所有此事务需要的行进行加锁,按顺序一次锁一行,查询就加共享锁,修改就加互斥锁。若第一阶段全部加锁成功,就开始第二阶段(只解锁):执行更新然后释放所有锁。若在第一阶段某个进程加锁时发生冲突,则该进程释放它所有加锁的行,然后重试第一阶段。
两阶段提交用到了两种锁,共享锁(也称为读锁,允许多个事务同时读取同一行)或互斥锁(也称为写锁,只要有写入就独占访问权限)。
两阶段锁定真正实现了串行化性质,它可以防止之前讨论的所有并发问题,也是性能损耗最大的选择,尤其是它可能会更频繁的导致死锁出现。事务由于死锁而被中止后只能重试,这意味着巨大的开销。

总结

事务隔离界别和并发问题解决情况总结
在这里插入图片描述

参考

https://www.zhihu.com/question/458275373/answer/1873975439
https://zhuanlan.zhihu.com/p/69380112

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值