对数据库事务理解以及脏读、不可重复读以及幻读问题

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 对数据库事务理解以及脏读、不可重复读以及幻读问题

引言

事务就是能够把多个SQL给打包在一起,变成一个整体。因为有些操作是需要作为一个整体来完成的,比如转账操作,A给B转账100,那么A的账户余额就会减100,B的账户余额就会加100。如果在A转账的过程中,因为某些原因只执行到一半,那么A的账户减100,B的账户却没有加100,显然这种是不正确的状态。事务就是要保证避免出现这种不科学的状态,把整个转账操作打包成一个整体,要么全部执行,要么一个都不执行。关于事务把操作打包成一个整体,就叫做“原子性”,这也是事务最核心的特性。

关于在执行过程中出错,就一条都不执行,这里并不代表一条都没有执行,而是出错之后,自动恢复到执行之前的样子,在外界看来就是一条都没执行的样子。这里面涉及到了一个关键操作,“回滚”。回滚就是把执行过的操作逆向恢复回去,类似于ctrl+Z。数据库会把执行的每个操作都记录下来,如果某个操作出错,就会把事务中前面的操作进行回滚。根据之前进行的操作,进行逆向操作,前面是插入,回滚就删除,前面是删除,回滚就插入,前面是修改,回滚就改回去。关于保存操作记录是有很大开销的,一般地就把正在执行的事务的操作给记录下来。


事务的使用

1.开启事务:start transaction;

2.执行多条SQL语句

3.回滚或提交:rollback/commit; (开启事务之后,中间的这些sql不会立即就执行,而是先等commit再统一执行,保证原子性,rollback主动进行回滚)

rollback即是全部失败,commit即是全部成功。

示例:

start transaction;

-- A账户减少100

update accout set money=money-100where name = 'A';

-- B账户增加100

update accout set money=money+100where name = 'B';

commit;

数据库的事务主要有四大特征:

1.原子性:这是事务的初心,⼀个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执⾏过程中发⽣错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执⾏过⼀样。

2.一致性:事务执行前执行后都必须是数据合法的状态。一致性是事务要解决的问题,也是要依赖原子性来实现的,在事务开始之前和事务结束以后,数据库的完整性没有被破坏。

3.持久性:事务产生的修改,都是会写入硬盘的,即使程序重启或主机重启或掉电,事务都是可以正常工作的,保证修改是有效的。

4.隔离性:一个数据库服务器同时执行多个事务的时候,事务之间的相互影响程度。数据库允许多个并发事务同时对其数据进⾏读写和修改的能⼒,隔离性可以防⽌多个事务

并发执⾏时由于交叉执⾏⽽导致数据的不⼀致。事务隔离分为不同级别,包括读未提交(

Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串⾏化

(Serializable)。

谈谈脏读、不可重复读以及幻读问题

关于MySQL提供的四个隔离级别:

mysql服务器要同时给多个客户端提供服务,此时多个客户端之间,可能会同时发起事务,尤其是这多个事务在操作同一个数据库的同一个表的时候,就很有可能引起一些麻烦。如果隔离性越高,就意味着事务之间的并发程度越低,执行效率是越慢,但是数据的准确性是越高的。如果隔离性越低,就意味着事务之间的并发程度越高,执行效率是越快,但是数据的准确性是越低的。


MySQL提供的四个隔离级别,根据实际需求选择不同的隔离级别。


1.如果事务B正在写数据,然而事务A也在读取数据,因为针对的是同一份数据,那么这种情况就属于“脏读”问题,在这个场景下,事务间是完全并发的,没有任何限制,这个级别就是read uncommitted。为了解决“脏读”问题,就是降低并发性,提高隔离性,也就是给“写操作”加锁。比如事务B在写数据的时候,事务A是不能读取的。

2.为了解决“脏读”问题,给“写操作”加锁了,所以A只能在B写入完成之后才能读取,这个级别就是read committed。但是又引入了新的问题,当A正在读取数据的时候,这个时候B又开始写入数据了,导致A读取数据一半的时候后面的数据就变了。在一个事务中,连续两次读取的数据的结果不一致,这就是“不可重复读”问题。为了解决“不可重复读”问题,那么给“读操作”也加锁了,在A读取数据的时候,是不能写入数据的。这两个事务之间的并发程度被进一步降低了,隔离性进一步的提高了,运行速度进一步降低了,但是数据准确性进一步提高了。


3.为了解决“不可重复读”问题,给“写操作”和“读操作”都加锁了,这个级别就是repeatable read,针对同一个代码文件来说,事务B在写入数据的时候,事务A不能进行读取,同样,事务A在进行读取数据的时候,事务B也是不能进行写入数据的。但是随着又引入了新的问题,既然B在写入数据的时候,A不能进行读取,同样A在读取数据的时候,B不能写入数据,但是他们都不是一直傻等着的,他们各自也会去做其他的事情,比如新增或删除其他文件。此时,虽然读取的代码内容没有变,但是会发现文件的数量有变化,例如这种情况,在同一个事务中,两次读到的结果集不相同,这就是“幻读”问题。为了解决“幻读”问题,就只有实现串行化,完全舍弃并发,比如B在写入数据的时候,A什么都不干,就干等着,这个级别就是serializable。


总结:MySQL提供的四个隔离级别

1.read uncommitted(读未提交):不做任何限制,事务之间都是随意并发执行的,并发程度最高,隔离性最低,会产生脏读+不可重复读+幻读。

2.read committed(读已提交):对写操作加锁了,并发程度降低了,隔离性提高了。解决了脏读问题,仍然存在不可重复读+幻读。

3.repeatable read(可重复读):对写和读都加锁了,并发程度又降低了,隔离性又提高了.解决了脏读+不可重复读,可能存在幻读问题。

4.serializable(串行化):严格串行化,并发程度最低(串行执行的)隔离性最高。解决了脏读+不可重复读+幻读问题,执行速度最慢的。


MySQL的隔离级别是通过MySQL的配置文件来进行调整的,在开发中,根据实际问题的需求场景来决定选用哪一个级别。其中MySQL的默认级别是repeatable read。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 关系型数据库 数据库
事务隔离级别:保障数据库并发事务的一致性与性能
事务隔离级别:保障数据库并发事务的一致性与性能
|
2月前
|
算法 大数据 数据库
数据库事务:保障数据一致性的基石
数据库事务:保障数据一致性的基石
|
27天前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
2月前
|
SQL 关系型数据库 MySQL
使用关系型数据库事务的例子
【5月更文挑战第12天】本文介绍了设置MySQL事务的三种方式:全局、当前session和下一个事务,并提供了示例代码展示如何开始事务和设置隔离级别。还简述了引擎设置和数据源DSN格式。最后,讨论了SQL优化策略,包括选择合适的存储引擎、优化字段数据类型、建立索引、避免全表扫描等。
259 4
使用关系型数据库事务的例子
|
2月前
|
存储 关系型数据库 MySQL
了解如何在关系型数据库中处理事务
【5月更文挑战第12天】数据库事务确保数据的ACID特性,即原子性、一致性、隔离性和持久性。它们用于一组操作,要么全部成功,要么全部不执行,防止数据不一致。MySQL的InnoDB存储引擎严格支持事务。MySQL默认隔离级别为REPEATABLE READ
59 3
|
27天前
|
关系型数据库 MySQL 数据库
MySQL数据库基础第四篇(多表查询与事务)
MySQL数据库基础第四篇(多表查询与事务)
|
1月前
|
SQL 关系型数据库 MySQL
MySQL数据库——事务操作-begin-commit-rollback
MySQL数据库——事务操作-begin-commit-rollback
17 1
|
1月前
|
SQL 关系型数据库 MySQL
MySQL数据库——基础篇总结(概述、SQL、函数、约束、多表查询、事务)一
MySQL数据库——基础篇总结(概述、SQL、函数、约束、多表查询、事务)一
29 5
|
1月前
|
SQL 安全 关系型数据库
MySQL数据库——事务-简介、事务操作、四大特性、并发事务问题、事务隔离级别
MySQL数据库——事务-简介、事务操作、四大特性、并发事务问题、事务隔离级别
22 1
|
21天前
|
SQL Java 关系型数据库
JAVA数据库开发 - 事务
JAVA数据库开发 - 事务
23 0