首页 > 数据库 >并发给数据库带来的问题及解决方案

并发给数据库带来的问题及解决方案

时间:2023-07-30 23:04:29浏览次数:47  
标签:事务 隔离 数据 发给 解决方案 数据库 幻读 级别 读取

假设没有事务的隔离性,当两个事务并发地去操作数据库的表或者行的时候,那么会产生什么问题?

1

并发给数据库带来的问题

并发给数据库带来的问题及解决方案_不可重复读

1、读脏数据

A 事务修改了一个数据(假设 A 从 1 改为 2),B 事务读取 A 事务修改后的数据(B 读取到了 2),但由于某种原因 A 事务撤销了事务(这个数据回滚到 1),此时导致 B 事务读取到的数据不正确(B 认为数据是 2),这就表示 B 事务读取到了脏数据,一般称为脏读。

2、不可重复读

A 事务读取数据后(假设 A 读到了 1),B 事务执行更新操作(B 把 1 改成了 2),然后 B 事务提交(此时数据的值为 2);然后 A 事务再次读取数据(A 读到了 2),也就是说 A 事务两次读取操作得到了2个结果(第一次是 1,第二次是 2)。说明在一个事务里对同一个数据读取,得到的值不一致,后面的读操作获得了其他它事务提交的结果,这就表示 A 事务不可重复度。

3、幻读

A 事务读取价格小于 10 的产品数据(假设 A 读到了 100 条数据),B 事务往产品表里插了一条价格小于 10 的产品,然后 B 事务提交(此时价格小于 10 的产品有 101 条);然后 A 事务再次读取价格小于 10 的产品数据(A 读到了 101 条数据),也就是说 A 事务读取到了 B 事务新增的记录(第一次是 100 条,第二次是 101 条)。这就表示 A 事务发生了幻读。

幻读与不可重复读的区别:不可重复读是由其他事务的修改操作引发的读不一致,幻读是由于其他事务新增或者删除记录引发的读不一致。从结果上看,不可重复读和幻读差不多。但从控制的角度来看, 两者的区别就比较大。对于前者, 只需要锁住满足条件的记录。对于后者, 要锁住满足条件及其相近的记录。

事务并发带来的三大问题,无论是脏读,还是不可重复读,或者是幻读,它们都是数据库的读一致性的问题,都是在一个事务里面前后两次读取出现了不一致的情况。

2

MySQL 事务的隔离级别

并发给数据库带来的问题及解决方案_数据_02

针对事务并发给数据库带来的三个读一致性的问题,SQL92 标准为各个数据库厂商提供一定的事务隔离级别,来解决事务并发的问题。

1、读未提交(Read Uncommitted)

第一个隔离级别:读未提交(Read Uncommitted),又叫做 RU,一个事务可以读取到其他事务未提交的数据,会出现脏读,它没有解决任何的问题。

2、读提交(Read Committed)

第二个隔离级别:读提交(Read Committed),又叫做 RC,也就是一个事务只能读取到其他事务已提交的数据,不能读取到其他事务未提交的数据,它解决了脏读的问题,没有解决不可重复读和幻读的问题。

3、可重复读(Repeatable Read)

第三个隔离级别:可重复读(repeatable Read),又叫做 RR,它解决了不可重复读的问题,也就是在同一个事务里面多次读取同样的数据结果是一样的,没有解决幻读的问题。

4、串行化(Serializable)

第四个隔离级别:串行化(Serializable),在这个隔离级别里面,所有的事务都是串行执行的,也就是对数据的操作需要排队执行,已经不存在事务的并发操作了,所以它解决了所有的问题。

以上的四个隔离级别是 SQL92 的标准,但是不同的数据库厂商或者存储引擎的实现有一定的差异。

3

InnoDB 存储引擎支持的隔离级别

并发给数据库带来的问题及解决方案_隔离级别_03

在 MySQL InnoDB 存储引擎里,不需要使用串行化的隔离级别去解决所有问题,下面我们来通过一张表格来看一下 InnoDB 对数据库事务隔离级别的支持情况:

并发给数据库带来的问题及解决方案_不可重复读_04

从上面的表可以看出 InnoDB 支持的四个隔离级别和 SQL92 标准定义的基本一致,隔离级别越高,事务的并发度就越低。唯一的区别是 InnoDB 存储引擎在可重复读(RR) 的级别就解决了幻读的问题。这个也是 InnoDB 默认使用 RR 作为事务隔离级别的原因,既保证了数据的一致性,又支持较高的并发度。


标签:事务,隔离,数据,发给,解决方案,数据库,幻读,级别,读取
From: https://blog.51cto.com/javazyx/6903628

相关文章

  • 12-MySQL数据库的触发器
    12-MySQL数据库的触发器课程目标了解触发器简介。掌握MySQL触发器的创建和使用以及删除。12.1触发器简介触发器是一个被指定关联到一个表的数据库对象,当对一个表的特定事件(例如增、删、改、查表中记录)出现时,它将会被激活。触发器具有MySQL语句在需要时才被执行的特点,即某条(或某......
  • 11-MySQL数据库的存储过程
    11-MySQL数据库的存储过程课程目标了解存储过程简介、关于MySQL的存储过程。掌握MySQL存储过程的创建、调用、查询、修改、删除、控制语句、基本函数。11.1存储过程简介我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(StoredProcedure)是一组为了完......
  • 10-DBA命令和数据库设计的三范式
    10-DBA命令和数据库设计的三范式课程目标掌握新建用户、授权、回收权限、导出导入、第一范式、第二范式、第三范式、三范式总结。10.1新建用户createuserusernameidentifiedby'password';说明:username——你将创建的用户名,password——该用户的登陆密码,密码可以为空,如果......
  • 前端工程化解决方案
    引言在大前端的趋势下,传统的前端开发模式已经不能很好地承载实际的项目需求。因此,我们需要一系列解决方案来使项目变得规范、可配置、易于优化等。本文将针对这个问题进行简单分析,讲解前端工程化的概念、落地实践,并给出一系列解决方案。本篇文章是本人在2020年时推进公司内部......
  • Mysql数据库常用操作命令
    //创建数据库>create databasedatabase_name;eg;createdatabasesorder;>useorder;//选择数据库>showtables;//显示数据库order创建的所有数据表>dropdatabaseorder;//删除数据库order,删除数据库后,数据表中的数据会全部被删除,所以删除前一定要做好数据......
  • “Java:不支持发行版本5”的解决方案
      cltr+shift+alt+s出现此页面 本地安装的jdk是8版本,所以这里显示的就是8版本,这里没有问题向下找module模块发现这里的“langeagelevel”是5将它修改成对应的版本  到File里找Settings→ Build→Compiler → javacompiler 修改成对应java版......
  • MAC中Java实现多版本JDK并存并随时切换的解决方案
    编辑SHELL配置文件,新版macOS默认使用的是zsh,打开终端,编辑zsh的配置文件.zshrcvi.zshrc在配置文件的末尾添加下面的内容:#>>>Java多版本共存exportJAVA_11_HOME=`/usr/libexec/java_home-v11`exportJAVA_17_HOME=`/usr/libexec/java_home-v17`#defaultJavaversi......
  • Mysql数据库中数据量特别大,读取特别慢,已经做了索引,怎么优化
    当MySQL数据库中的数据量特别大,读取操作变得特别慢,即使已经添加了索引,仍然需要进一步优化。下面是一些建议以及示例代码来优化这种情况:使用合适的索引:确保为频繁查询的列添加了合适的索引。可以使用EXPLAIN语句来分析查询的执行计划,检查是否正确使用了索引。示例代码:sqlCopycodeE......
  • websocket服务端,运行后始终无法连接的解决方案
    javax.websocket.DeploymentException:TheHTTPresponsefromtheserver[404]didnotpermittheHTTP解决办法:少两个文件:WebSocketConfig.java@ConfigurationpublicclassWebSocketConfig{/***注入一个ServerEndpointExporter,该Bean会自动注册使用@Server......
  • GoRedisLock:Golang保障数据一致性的分布式锁解决方案
    在现代分布式系统中,多个节点之间共享资源是常见的需求。然而,并发访问共享资源可能导致数据不一致性和竞争条件。为了解决这些问题,我们需要引入分布式锁。GoRedisLock是一个出色的分布式锁库,它结合了Go语言和Redis的优势,提供了稳定高效的分布式并发控制解决方案。**项目地址:**htt......