深入了解MySQL中的事务、4大特性、隔离级别

本篇文章是mysql的进阶学习,给大家详细介绍一下mysql中的事务、4大特性(acid)以及事务的隔离级别,希望对大家有所帮助!

深入了解MySQL中的事务、4大特性、隔离级别

【相关推荐:mysql视频教程】

本文操作和测试所用的环境版本是5.7.21

mysql> select version();+-----------+| version() |+-----------+| 5.7.21    |+-----------+1 row in set (0.00 sec)

记住:我们常见的MySQL存储引擎中只有InnoDB是支持事务的。所以下面的操作也都是在InnoDB下做的。

一. 什么是事务

事务就是现实中抽象出来一种逻辑操作,要么都执行,要么都不执行,不能存在部分执行的情况。

比较经典的案例就是银行转账:小A向小B转账100元

正常的情况:小A的账户扣减100元,小B的账户增加100元。

非正常情况: 小A的账户扣减100元,小B账户金额不变。

非正常情况下,小A账户扣减100之后银行系统出现问题,小B账户增加100元的操作并没有执行。也就是两边金额对不上了,小A不愿意,小B不愿意,银行也不愿意啊。事务的出现就是为了避免非正常情况的出现,让大家都满意。

二. 事务的4大特性(ACID)

1. 原子性(Atomicity)

事务的操作是不可分割的,要么都操作,要么都不操作,就像转账一样,不存在中间状态。而且这个原子性不是说只有一个动作,可能会有很多的操作,但是从结果上看是不可分割的,也就是说原子性是一个结果状态。

2. 一致性(Consistency)

执行事务的前后,数据保持一致,就像银行账户系统一样无论事务是否成功,两者的账户总额应该是一样的。

3. 隔离性(Isolation)

多个事务同时操作数据的时候,多个事务直接互相隔离,不会互相影响。

4. 持久性(Durability)

一个事务在提交后对数据的影响是永久的,写入磁盘中不会丢失。

三. 显式事务、隐式事务

mysql的事务分为显式事务隐式事务,默认的事务是隐式事务,由变量autocommit 在操作的时候会自动开启,提交,回滚。

控制的关键命令如下

set autocommit=0; -- 关闭自动提交事务(显式)set autocommit=1; -- 开启自动提交事务(隐式)  -- 当autocommit=0的时候手动控制事务rollback; -- 回滚事务commit;  -- 提交事务-- 当autocommit=1 自动提交事务,但是可以控制手动提交start transaction; -- 开启事务(或者用begin开启事务)commit; -- 提交事务rollback; -- 回滚事务SAVEPOINT 保存点名称;  -- 保存点(相当于存档,可以不用回滚全部操作)rollback to  保存点;  -- 回滚到某个保存点 (这个后面就不测试,知道有这个操作就行)

先建一张表ajisun

mysql> create table ajisun(id int(5), name varchar(20) character set utf8  COLLATE utf8_bin ) engine=innodb character set= utf8mb4 COLLATE = utf8mb4_bin;Query OK, 0 rows affected (0.03 sec)

1. 隐式事务

-- 看下当前autocommit的状态是,默认是on状态mysql> show variables like 'autocommit'; +---------------+-------+| Variable_name | Value |+---------------+-------+| autocommit    | ON    |+---------------+-------+1 row in set (0.01 sec)--  插入一条数据mysql> insert into ajisun values(1,'阿纪');Query OK, 1 row affected (0.00 sec)mysql> rollback;-- 执行rollback 也是没有效果的,还是能够查询到插入的数据(不需要我们手动控制commit)mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    1 | 阿纪   |+------+--------+1 row in set (0.00 sec)

2. 显式事务方式1

显式事务由我们自己控制事务的开启,提交,回滚等操作

-- 开启显式事务-回滚mysql> set autocommit=0;Query OK, 0 rows affected (0.00 sec)mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    1 | 阿纪   |+------+--------+1 row in set (0.00 sec)mysql> insert into ajisun values(2,'纪先生');Query OK, 1 row affected (0.00 sec)-- 插入后可以看见2条数据mysql> select * from ajisun;+------+-----------+| id   | name      |+------+-----------+|    1 | 阿纪      ||    2 | 纪先生    |+------+-----------+2 rows in set (0.00 sec)-- 回滚之后上面插入的数据就没了mysql> rollback;Query OK, 0 rows affected (0.00 sec)mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    1 | 阿纪   |+------+--------+1 row in set (0.00 sec)
-- 插入一条数据mysql> insert into ajisun values(2,'ajisun');Query OK, 1 row affected (0.01 sec)-- 提交mysql> commit;Query OK, 0 rows affected (0.00 sec)-- 回滚mysql> rollback;Query OK, 0 rows affected (0.00 sec)-- 先提交commit,在rollback 数据依然存在,说明commit生效,事务已提交,回滚就不生效了。mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    1 | 阿纪   ||    2 | ajisun |+------+--------+2 rows in set (0.00 sec)

3. 显式事务方式2

使用start transaction

先改成默认的事务 set autocommit=1;

-- 开启事务mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> delete from ajisun where id=1;Query OK, 1 row affected (0.00 sec)-- 提交事务mysql> commit;Query OK, 0 rows affected (0.01 sec)mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    2 | ajisun |+------+--------+1 row in set (0.00 sec)
-- 开启事务mysql> start transaction;Query OK, 0 rows affected (0.00 sec)mysql> delete from ajisun where id =2;Query OK, 1 row affected (0.01 sec)-- 回滚事务mysql> rollback;Query OK, 0 rows affected (0.01 sec)-- 删除操作失效了mysql> select * from ajisun;+------+--------+| id   | name   |+------+--------+|    2 | ajisun |+------+--------+1 row in set (0.00 sec)

四. 并发事务中的问题

如果对表的操作同一时间只有一个事务就不会有问题,但是这是不可能的。现实中都是尽可能的利用,多个事务同时操作。多个事务就会带来不少的问题,例如脏读脏写`不可重复读幻读

1. 脏读

一个事务读取到另一个未提交事务修改后的数据 这就是脏读。

例如两个事务a,b: 同时操作一条记录

a事务修改记录后还没有正式提交到数据库,这时b事务去读取,然后用读取到的数据进行后续操作。

如果a事务回滚了,这个修改后的数据就不存在了,那么b事务就是在使用一个不存在的数据。这种就是脏数据。

2. 脏写(数据丢失)

一个事务修改了另一个未提交事务修改过的数据

例如两个事务a,b: 同时操作一条记录

a事务修改后没有提交, 接着b事务也修改同一条数据,然后b事务提交数据。

如果a事务回滚自己的修改,同时也把b事务的修改也回滚了,造成的问题就是:b事务修改了 也提交了,但是数据库并没有改变,这种情况就是脏写。

3. 不可重复读

一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。

也就是在同一个事务中多次读取同一条记录,得到的内容都不一样(在每次读取之前都有其他事务完成修改并提交),这就是不可重复读

天工大模型 天工大模型

中国首个对标ChatGPT的双千亿级大语言模型

天工大模型 115 查看详情 天工大模型

4. 幻读

在一个事务内 相同条件查询数据,先后查询到的记录数不一样

也就是一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来,那就意味着发生了幻读

不可重复读和幻读的区别:不可重复读重点在于同一条记录前后数据值不一样(内容的变化),而幻读重点在于相同查询条件前后所获取的记录数不一样(条数的变化)

五. 事务的隔离级别

上面说的事务的并发问题,在不同的场景下要求不一样,能接受的问题也不一样。他们之间的严重性排序如下:

脏写 > 脏读 > 不可重复读 > 幻读

MySQL中提供了4种隔离级别来处理这几个问题,如下

隔离级别 脏读 不可重复读 幻影读

READ- UNCOMMITTED√√√READ-COMMITTED×√√REPEATABLE-READ××√SERIALIZABLE×××

SQL 标准定义了四个隔离级别:

READ-UNCOMMITTED(读未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读不可重复读幻读。但是并发度最高READ-COMMITTED(读已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读不可重复读仍有可能发生。REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读不可重复读,但幻读仍有可能发生。SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,该级别可以防止脏读不可重复读以及幻读。并发度也是最低的

MySQL默认采用的 REPEATABLE_READ 隔离级别 Oracle默认采用的 READ_COMMITTED 隔离级别

1. 如何设置隔离级别

可以通过变量参数transaction_isolation 查看隔离级别

mysql> SELECT @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| REPEATABLE-READ         |+-------------------------+1 row in set (0.00 sec)mysql> show variables like '%transaction_isolation%';+-----------------------+-----------------+| Variable_name         | Value           |+-----------------------+-----------------+| transaction_isolation | REPEATABLE-READ |+-----------------------+-----------------+1 row in set (0.02 sec)

修改的命令:SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL $[level];

level的值就是4中隔离级别READ-UNCOMMITTED READ-COMMITTED REPEATABLE-READ SERIALIZABLE

设置全局隔离级别

只对执行完该语句之后产生的会话起作用。

当前已经存在的会话无效。

set global transaction_isolation='read-uncommitted';set global transaction_isolation='read-committed';set global transaction_isolation='repeatable-read';set global transaction_isolation='serializable';

例如:

会话A

mysql> set global transaction_isolation='serializable';Query OK, 0 rows affected (0.01 sec)mysql> select @@global.transaction_isolation;+--------------------------------+| @@global.transaction_isolation |+--------------------------------+| SERIALIZABLE                   |+--------------------------------+1 row in set (0.00 sec)-- 当前会话(设置之前就已经存在的会,级别是默认的)mysql> select @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| REPEATABLE-READ         |+-------------------------+1 row in set (0.00 sec)

会话B(set之后新建的会话)

mysql> select @@global.transaction_isolation;+--------------------------------+| @@global.transaction_isolation |+--------------------------------+| SERIALIZABLE                   |+--------------------------------+1 row in set (0.00 sec)mysql> select @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| SERIALIZABLE            |+-------------------------+1 row in set (0.00 sec)

设置会话的隔离级别

对当前会话的所有后续的事务有效

该语句可以在已经开启的事务中间执行,但不会影响当前正在执行的事务。

如果在事务之间执行,则对后续的事务有效。

set session transaction_isolation='read-uncommitted';set session transaction_isolation='read-committed';set session transaction_isolation='repeatable-read';set session transaction_isolation='serializable';

比如:

会话A

mysql> set session transaction_isolation='read-uncommitted';Query OK, 0 rows affected (0.00 sec)mysql> select @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| READ-UNCOMMITTED        |+-------------------------+1 row in set (0.00 sec)

新建会话B(依然是默认的级别:可重复读)

mysql> select @@transaction_isolation;+-------------------------+| @@transaction_isolation |+-------------------------+| REPEATABLE-READ         |+-------------------------+1 row in set (0.00 sec)

2. 怎么选择隔离级别

一般情况下默认的可重复读就好了,一般很少改这个,除非业务场景特殊

记住一点:隔离级别越高,并发问题就越少,但并发性也就越低,所以还是要根据业务选择来。

六. 总结

事务的四大特性:原子性,一致性,隔离性,持久性

事务的常见命令:

set autocommit=0/1; -- 关闭/开启自动提交事务start transaction; -- 开启事务(或者用begin)rollback; -- 回滚事务commit; -- 提交事务

并发事务的问题:脏写 > 脏读 > 不可重复读 > 幻读

需要熟悉事务的4种隔离级别以及MySQL默认级别

怎么设置隔离级别(global,session)

更多编程相关知识,请访问:编程入门!!

以上就是深入了解MySQL中的事务、4大特性、隔离级别的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/289166.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月4日 19:51:36
下一篇 2025年11月4日 19:54:48

相关推荐

  • 网络进化!

    Web 应用程序从静态网站到动态网页的演变是由对更具交互性、用户友好性和功能丰富的 Web 体验的需求推动的。以下是这种范式转变的概述: 1. 静态网站(1990 年代) 定义:静态网站由用 HTML 编写的固定内容组成。每个页面都是预先构建并存储在服务器上,并且向每个用户传递相同的内容。技术:HT…

    2025年12月24日
    000
  • 为什么多年的经验让我选择全栈而不是平均栈

    在全栈和平均栈开发方面工作了 6 年多,我可以告诉您,虽然这两种方法都是流行且有效的方法,但它们满足不同的需求,并且有自己的优点和缺点。这两个堆栈都可以帮助您创建 Web 应用程序,但它们的实现方式却截然不同。如果您在两者之间难以选择,我希望我在两者之间的经验能给您一些有用的见解。 在这篇文章中,我…

    2025年12月24日
    000
  • CSS如何实现任意角度的扇形(代码示例)

    本篇文章给大家带来的内容是关于CSS如何实现任意角度的扇形(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 扇形制作原理,底部一个纯色原形,里面2个相同颜色的半圆,可以是白色,内部半圆按一定角度变化,就可以产生出扇形效果 扇形绘制 .shanxing{ position:…

    2025年12月24日
    000
  • html中怎么运行sql语句_html中运行sql语句方法【教程】

    必须通过后端服务执行SQL操作。一、PHP与MySQL交互:使用PHP脚本在服务器端连接数据库,执行查询并嵌入HTML输出,避免硬编码凭证。二、Ajax调用API:前端通过JavaScript向后端API发送请求,服务端执行SQL并返回JSON数据,前端动态渲染结果。三、SQLite与JavaScr…

    2025年12月23日
    000
  • html手机怎么运行_手机运行html方法【教程】

    1、使用手机浏览器可直接打开本地HTML文件,只需通过文件管理器点击文件并选择浏览器打开即可预览;2、借助Spck Editor等专用编辑器应用能实现实时编辑与预览,适合开发调试;3、对于含JavaScript或需服务器支持的动态内容,应安装KSWEB类应用搭建本地服务器,再通过http://loc…

    2025年12月23日
    000
  • html如何连接_连接HTML与数据库或API接口【接口】

    HTML无法直接连接数据库或调用API,需借助JavaScript fetch、PHP中转、Node.js后端或Python Flask等服务端技术实现动态数据交互。 如果您希望在网页中动态获取数据,HTML本身无法直接连接数据库或调用API接口,必须借助服务器端语言或JavaScript等客户端技…

    2025年12月23日
    000
  • HTML如何添加批注功能_评论系统实现方案【教程】

    可实现HTML文本批注功能的四种方案:一、基于HTML5自定义属性与JS的静态批注;二、遵循W3C标准的语义化批注;三、嵌入Utterances或Giscus等第三方评论系统;四、自建AJAX评论后端+前端组件。 如果您希望在HTML页面中为特定文本添加可交互的批注功能,或构建一个轻量级的评论系统,…

    2025年12月23日
    000
  • html怎么在本地服务器运行_本地服务器运html方法【指南】

    使用本地服务器运行HTML文件需通过HTTP协议,可选Python命令启动服务、Node.js的http-server、VS Code的Live Server插件或XAMPP等工具,确保AJAX等功能正常。 要在本地服务器运行HTML文件,不能直接双击打开,因为部分功能(如AJAX、API调用)需要…

    2025年12月23日
    200
  • phpstudy怎么运行本地html_phpstudy运行本地html方法【教程】

    确保Apache或Nginx服务已启动;2. 将HTML文件放入WWW目录;3. 浏览器访问localhost即可运行页面。 在使用 PHPStudy 时,运行本地 HTML 文件非常简单。PHPStudy 是一个集成了 Apache/Nginx、PHP 和 MySQL 的集成环境工具,主要用于本地…

    2025年12月23日
    000
  • HTML页面如何生成短链接_URL压缩转换方法【攻略】

    可借助第三方服务、API调用、Nginx反向代理、PHP脚本或GitHub Pages五种方式将HTML页面URL转为短链接:1.用bit.ly等平台手动缩短;2.调用Bitly API批量生成;3.配置Nginx rewrite规则重定向;4.部署PHP+MySQL实现动态跳转;5.利用GitHu…

    2025年12月23日
    000
  • Java JDBC中SQL INSERT语句的常见语法错误及修复指南

    本文旨在解决java jdbc应用中常见的sql `insert`语句语法错误,特别是因缺少括号而导致的错误。我们将深入分析错误信息,指出问题根源,并提供正确的sql语句范例及java jdbc `preparedstatement`的使用方法。文章还将涵盖jdbc数据库操作的最佳实践、错误处理和调…

    2025年12月23日
    000
  • wampserver怎么运行html程序_wampserver运行html程序方法【教程】

    使用WampServer运行HTML程序需将文件放入www目录,启动Apache服务后通过http://localhost/项目路径访问,确保在本地服务器环境下正确解析运行。 如果您在本地开发网页,但无法正确查看HTML文件的运行效果,可能是由于未通过本地服务器环境进行访问。WampServer 提…

    2025年12月23日
    000
  • 平板怎么运行html代码_平板运行html代码步骤【指南】

    可在平板上通过四种方式查看HTML效果:一、用浏览器直接打开本地.html文件;二、使用JSFiddle等在线编辑器实时预览;三、安装Acode等编程应用离线编写并预览;四、通过KSWEB搭建本地服务器运行含动态内容的页面。 如果您希望在平板设备上查看或测试HTML代码的效果,但不确定如何操作,则可…

    2025年12月23日
    000
  • html上怎么运行php代码吗_html中运行php代码方法【教程】

    要使PHP代码在HTML中执行,必须通过支持PHP的服务器环境。首先将文件保存为.php格式并部署到配置好PHP模块的服务器(如Apache)根目录,通过http://localhost访问;或修改服务器配置(如.htaccess)令.html文件解析PHP;推荐使用.php文件混合HTML与PHP…

    2025年12月23日
    000
  • html怎么用sublime运行php_sublime运行html中php方法【教程】

    可在Sublime Text中通过配置PHP环境变量并创建Build System运行PHP代码,或使用PHP内置服务器、XAMPP等集成环境结合浏览器预览实现解析与调试。 如果您在使用Sublime Text编辑HTML或PHP文件时,希望直接运行PHP代码并查看输出结果,但发现无法像在浏览器中那…

    2025年12月23日
    000
  • PHP表单提交后防止页面刷新并保留数据与错误提示的教程

    本教程旨在解决php表单提交时页面刷新、用户输入数据丢失以及错误提示显示不佳的问题。核心方法是利用服务器端php的`$_post`变量,在表单提交并进行服务器端验证失败后,不进行页面重定向,而是直接在当前页面重新渲染表单,同时回填用户之前输入的数据并显示验证错误信息,从而显著提升用户体验。 引言:优…

    2025年12月23日
    000
  • 如何通过JavaScript/jQuery获取HTML元素内容并与PHP后端交互

    本教程详细阐述了如何利用JavaScript和jQuery从HTML页面中动态获取特定` `标签的文本内容,并进一步探讨了如何将这些前端捕获的数据通过AJAX技术安全地传递给PHP后端进行处理,例如执行SQL查询。文章涵盖了从前端事件触发、数据捕获到后端数据接收、处理及安全防护的全流程,旨在提供一个…

    2025年12月23日
    000
  • php怎么在html5中运行_php在html5中运行方法【教程】

    PHP在服务器端运行,通过嵌入HTML5文件生成动态内容。1. PHP与HTML5协同工作:PHP代码嵌入.html或.php文件,由服务器解析后输出纯HTML至浏览器。2. 创建index.php文件,使用标准HTML5结构,在其中插入等PHP代码,实现动态内容展示。3. 搭建本地环境可选用XAM…

    2025年12月23日 好文分享
    000
  • epp4怎么运行html文件_EPP4运行html文件步骤【指南】

    首先确认EPP4已安装并启动Apache服务,将HTML文件放入www目录后,通过http://localhost/路径访问即可预览页面,确保文件位置与路径正确。 打开EPP4后运行HTML文件并不复杂,只需正确操作即可在浏览器中预览页面效果。EPP4(Easy PHP Pack 4)是一个集成开发…

    2025年12月23日
    000
  • html怎么用浏览器运行php_浏览器运html中php文件方法【教程】

    正确答案是搭建本地开发环境。需安装XAMPP等集成工具,将.php文件放入htdocs目录,通过http://localhost访问,确保服务器解析PHP并返回HTML给浏览器显示。 PHP 是服务器端语言,不能直接通过浏览器像 HTML 那样双击打开运行。你看到的“在浏览器中运行 PHP”其实是指…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信