数据库的隔离级别

数据库的隔离级别本文主要介绍了数据库中的隔离级别,以及其会产生的场景。

大家好,又见面了,我是你们的朋友全栈君。

详解数据库的隔离级别

1,数据库事务的四大特性

数据库事务:是作为单个工作单元而执行的一系列操作,如查询和修改数据,甚至是修改数据的定义。

  1. 原子性 (Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。即要么都成功,要么都失败。

在这里插入图片描述

如上图: 小明要给小红转200元,那么这个过程包括两个步骤:小明给银行转200:1000-200=800;银行给小红转账200:1000+200=1200。原子性规定这两个步骤一起成功,或者一起失败,不能只发生其中一个动作。如果小明只减200或者小红只加200,那么银行就会乱套。

  1. 一致性 (Consistency)

一致性是指事务前后数据的完整性必须保持一致。

在这里插入图片描述

仍是如上图:小红和小明初始的金额总数为:1000+1000=2000;在转账完成之后,小明余额800元,小红余额1200元。俩人金额总数为:800+1200=2000。一致性表示事务完成后,符合逻辑运算。

  1. 隔离性 (Isolation)

隔离性是指多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

在这里插入图片描述

如上图:多个用户同时操作,产生俩个事务:1,小明给小红转账200;2,小刚给小红转账100。隔离性是指小明和小刚给小红转账这两个事务不会相互影响。

  1. 持久性 (Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

仍是如上图的例子:小明给小红转账200元:

操作前小明:1000,小红:1000
操作后小明:800,小红:1200
如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为:小明:1000,小红:1000;
如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该仍为
A:800,B:1200,不会恢复到原始。

2,数据库的隔离级别问题

2.1脏读

脏读是指一个事务在执行过程中读取到另一个事务未提交的数据的现象就是脏读。

如上图小明和小刚给小红转账:

在这里插入图片描述

1、在小明给小红转账过程中,银行对小红的银行卡余额进行了修改为1200,小刚给小红转账时读取了小红的银行卡余额修改后的数据,并加100为1300了。

2、由于某些原因,小明撤销了转账的事务转账事务没有完成提交,发生了RollBack操作,则小刚读取的数据就是脏数据。这样就产生了数据错误。

PS:银行实际转账流程不是如此,该例子只是为了便于理解脏读。

2.2 不可重复读

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

事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。

注: 不可重复读和脏读的区别是,脏读读取到的是一个未提交的数据,而不可重复读读取到的是前一个事务提交的数据;而不可重复读在一些情况也并不影响数据的正确性,比如需要多次查询的数据也是要以最后一次查询到的数据为主。

2.3 虚读(幻读)

幻读是事务非独立执行时发生的一种现象。例如事务1批量对一个表中某一列列值为1的数据修改为2的变更,但是在这时,事务2对这张表插入了一条列值为1的数据,并完成提交。此时,如果事务T1查看刚刚完成操作的数据,发现还有一条列值为1的数据没有进行修改,而这条数据其实是2刚刚提交插入的,这就是幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点同脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。

注:

  1. 幻读和不可重复读都是读取了另一条已经提交的事务。不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体

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

3,数据库的锁机制

3.1 共享锁

由读表操作加上的锁,加锁后其他用户只能获取该表或行的共享锁,不能获取排它锁,也就是说只能读不能写。

3.2 排它锁

由写表操作加上的锁,加锁后其他用户不能获取该表或行的任何锁,典型是mysql事务。

3.3 表锁

给整张表加锁

3.4 行锁

给行数据加锁

因此锁可以分为表级共享锁行级共享锁表级排它锁行级排它锁

4,数据库的隔离级别

4.1 读取未提交(READ-UNCOMMITTED)

在这个隔离级别,select语句不加锁,所有事务都可以“看到”未提交事务的执行结果。读取未提交数据,也被称为“读脏”。

4.2 读取已提交(READ-COMMITTED)

大多数数据库系统的默认隔离级别(但是不是MySQL的默认隔离级别),满足了隔离的早先简单定义:一个事务开始时,只能“看见”已经提交事务所做的改变,一个事务从开始到提交前,所做的任何数据改变都是不可见的,除非已经提交。可避免脏读的发生,在互联网大数据量,高并发量的场景下,几乎不会使用上述两种隔离级别。

4.3 可重复读(REPEATABLE-READ)

MySQL数据库默认的隔离级别。该级别解决了READ UNCOMMITTED隔离级别导致的问题。它保证同一事务的多个实例在并发读取事务时,会“看到同样的”数据行。不过,这会导致另外一个棘手问题“幻读”。InnoDB和Falcon存储引擎通过多版本并发控制机制解决了幻读问题。

4.4 可串行化(SERIALIZABLE)

该级别是最高级别的隔离级。它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简而言之,可串行化是在每个读的数据行上加锁。在这个级别,可能导致大量的超时Timeout和锁竞争Lock Contention现象,实际应用中很少使用到这个级别,但如果用户的应用为了数据的稳定性,需要强制减少并发的话,也可以选择这种隔离级。

根据数据库的隔离级别问题可以看出数据库的隔离级别的缺点:

隔离级别 脏读可能性 不可重复读可能性 幻读可能性 加锁读
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE

5,数据库的三大范式

范式是数据库设计时遵循的一种规范,不同的规范要求遵循不同的范式。

5.1 第一范式

数据库的属性不可分割,即每个属性都是不可分割的原子项。即保证数据库的每一列不可再分。

5.2 第二范式

前提:必须满足第一范式。不存在部分依赖,即非主属性必须完全依赖于主属性。即第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

5.3 第三范式

前提:必须满足第一、第二范式。不存在传递依赖,即非主属性不能与非主属性之间有依赖关系,非主属性必须直接依赖于主属性,不能间接依赖主属性。即第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

作者:王二黑_Leon
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
本文章仅作为自学所用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143037.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)


相关推荐

  • 小程序推广赚佣金平台_亦笑天有声工作室微信公众号

    小程序推广赚佣金平台_亦笑天有声工作室微信公众号LNMP的配置与优化 一、LNMP的下载 LNMP一键安装包是一个用LinuxShell编写的可以为CentOS/RadHat/Fedora、Debian/Ubuntu/Raspbian/DeepinVPS或独立主机安装LNMP(Nginx/MySQL/PHP)、LNMPA(Nginx/MySQL/PHP/Apache)、LAMP(Apache/MySQL/PHP)生产环境…

  • 低延迟视频传输_网络延时

    低延迟视频传输_网络延时微信后台如何应对像跨年,特殊时刻(比如2022年2月22日22时22分22秒)这样的朋友圈突发流量,可做如下策略(只是比如):优先让发一张图片的成功。九宫格只成功一部分,剩余的强有损压缩。朋友多的优先成功。(也可以反过来)设置三天可见的优先成功。(也可以反过来)年轻女性优先成功。(这个没毛病)历史点赞多的优先成功。(也可以反过来)头像穿西装打领带的经理统统失败。…在不影响P99用户体验的前提下,提供有损服务,保证核心可用性,这就是柔性。但数据传输的思维定势并不认可柔性。受TCP的影

  • 什么是系统平均负载(Load average)

    什么是系统平均负载(Load average)一、什么是系统平均负载(Loadaverage)?在Linux系统中,uptime、w、top等命令都会有系统平均负载loadaverage的输出,那么什么是系统平均负载呢?LoadAver

  • httprunner(8)用例调用-RunTestCase[通俗易懂]

    httprunner(8)用例调用-RunTestCase[通俗易懂]前言一般我们写接口自动化的时候,遇到复杂的逻辑,都会调用API方法来满足前置条件,Pytest的特性是无法用例之间相互调动的,我们一般只调用自己封装的API方法。而httprunner支持用例之间

  • win10共享打印错误0x0000006_win7打印机共享错误0x000006,连接成功,打印测试报错…[通俗易懂]

    win10共享打印错误0x0000006_win7打印机共享错误0x000006,连接成功,打印测试报错…[通俗易懂]win7打印机共享出现错误0x000006,建议一直按住左shift键,然后点击电源的重启,疑难解答-高级选项-启动设置-重启,选择4或者F进入安全模式,在安全模式下将第三方优化软件卸载,清理磁盘。然后回到正常模式,开启上面所述的服务,启动server服务,再次设置打印机共享。打印机(Printer)是计算机的输出设备之一,用于将计算机处理结果打印在相关介质上。打印机共享,也就是平常说的局域网内…

  • Pytest(11)allure报告[通俗易懂]

    Pytest(11)allure报告[通俗易懂]前言allure是一个report框架,支持java的Junit/testng等框架,当然也可以支持python的pytest框架,也可以集成到Jenkins上展示高大上的报告界面。mac环境:

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号