Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
深入了解MySQL中的事务、4大特性、隔离级别_创想鸟

深入了解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)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
VSCode代码片段创建和使用教程
上一篇 2025年11月4日 19:54:29
菜鸟app的无人驿站或者快递柜怎么使用_菜鸟app无人驿站/快递柜使用方法
下一篇 2025年11月4日 19:54:30

相关推荐

  • 减少PHP与MySQL数据库通信的延迟

    减少php与mysql数据库通信的延迟可以通过以下策略:1. 优化数据库查询,使用索引提升查询速度;2. 减少数据库连接次数,使用连接池管理连接;3. 查询优化,使用explain分析查询计划;4. 使用缓存,如redis,减少数据库查询次数。这些方法能显著提升应用性能,但需权衡利弊,确保系统稳定性…

    2026年9月24日
    000
  • 解决MySQL事件event定义中文乱码的方法

    mysql的event事件处理中文乱码问题主要由字符集设置不当引起,解决方法包括以下步骤:1. 统一数据库、表和字段的字符集为utf8mb4,创建或修改时显式指定字符集;2. 设置连接层字符集,在连接后执行set names ‘utf8mb4’或在程序连接参数中指定chars…

    2026年9月24日
    300
  • Java中接口常量和类常量的使用区别

    接口常量默认public static final,用于行为契约但易导致职责模糊;类常量可用不同访问修饰符,更适合封装和维护。现代Java推荐使用专用常量类、枚举、私有静态常量或配置文件管理常量,以提升代码清晰度与可维护性。 Java中接口常量和类常量,核心区别在于它们的定义位置和隐式属性。接口常量…

    2026年9月24日
    000
  • mysql中in的用法详解 mysql in查询全面解析

    in操作符在mysql中用于检查值是否在指定列表内。1) 基本用法:select from users where name in (‘john’, ‘jane’, ‘jack’)。2) 子查询用法:select from or…

    2026年9月24日
    000
  • PHP 中如何将 JSON 数组值声明为变量

    本文介绍了如何在 PHP 中从数据库获取数据并将其编码为 JSON 格式,然后通过 AJAX 请求传递到另一个页面。重点讲解了如何在接收页面解析 JSON 数据,并将 JSON 数组中的特定值提取并赋值给变量,以便在后续的 PHP 函数中使用。 从数据库获取数据并编码为 JSON 首先,我们需要从数…

    2026年9月24日
    000
  • mysql中是什么意思 mysql语法符号含义解析

    mysql 中的符号和关键字是与数据库交互的基本工具,正确使用它们可以提高工作效率和查询准确性。1. 逗号(,)用于分隔列表中的元素,如列名和值。2. 点号(.)用于访问表中的列或调用函数。3. 星号(*)用于选择所有列,但应避免使用以提高查询性能。4. 百分号(%)用于 like 操作中的模式匹配…

    2026年9月24日
    100
  • PHP+MySQL培训课程的费用性价比分析

    php+mysql培训课程的性价比高,具体体现在:1.课程内容深度和广度,涵盖框架使用和项目经验;2.实用性和就业前景,提供实战项目和就业指导;3.师资力量和教学方式,名师能激发学习热情;4.学习资源和社区支持,提供丰富资料和交流平台。 在考虑报名PHP+MySQL培训课程之前,很多人都会问:这些课…

    2026年9月24日
    200
  • 使用MySQL命令行客户端进行交互式管理

    使用MySQL命令行客户端进行交互式管理使用MySQL命令行客户端进行交互式管理使用MySQL命令行客户端进行交互式管理使用MySQL命令行客户端进行交互式管理

    mysql命令行客户端的常用命令包括:1. 使用mysql -u 用户名 -p命令连接数据库;2. 执行show databases;查看所有数据库;3. 使用use 数据库名;选择数据库;4. 使用select * from 表名;查询数据;5. 使用insert into 表名 (列1, 列2)…

    2026年9月24日 • 用户投稿
    600
  • 数据实时迁移同步工具 CloudCanal v5.2.0.0 发布,支持 SaaS 全托管

    cloudcanal 免费社区版 是 clougence 公司推出的一款全自研、可视化、自动化数据迁移同步工具,具备 结构迁移、数据迁移、数据同步、数据校验、数据订正 等功能,支持 60+ 款流行关系型数据库、实时数仓、消息中间件、缓存数据库和搜索引擎之间数据互通,其中包含国产数据库 oceanba…

    2026年9月24日
    100
  • 怎么在mysql中创建数据库表 mysql建表完整流程解析

    在 mysql 中创建数据库表的步骤包括:1) 选择合适的数据类型,如 int、varchar、timestamp;2) 设置索引,如主键和唯一索引;3) 应用约束条件,如 not null 和 unique;4) 设计表结构以满足业务需求,如使用 foreign key 和 enum;5) 优化性…

    2026年9月24日
    100
  • hive安装配置实验

    一、安装前的准备工作 1. 配置并安装hadoop,请参考链接http://blog.csdn.net/wzy0623/article/details/50681554。 2. 下载以下安装包:mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz、apache-hive…

    2026年9月24日
    700
  • 命令行下MySQL中文乱码如何设置utf8编码

    mysql命令行中文乱码解决方法是统一各环节字符集为utf8mb4。具体步骤如下:1.查看当前编码设置,确认character_set相关变量是否为utf8或utf8mb4;2.修改配置文件,在[client]和[mysqld]下设置默认字符集为utf8mb4并重启服务;3.修改已有数据库和表的字符…

    2026年9月24日
    200
  • 如何解决MySQL安装时配置不生效的处理方法?

    如何解决MySQL安装时配置不生效的处理方法?如何解决MySQL安装时配置不生效的处理方法?如何解决MySQL安装时配置不生效的处理方法?如何解决MySQL安装时配置不生效的处理方法?

    配置mysql时遇到配置不生效的问题,常见原因包括配置文件路径错误、语法问题、命令行参数覆盖及数据目录权限或初始化问题。1. 配置文件路径是否正确?mysql只会读取特定路径的配置文件,建议使用命令mysql –help | grep “default options&#82…

    2026年9月24日 • 用户投稿
    100
  • mysql如何优化表结构?表结构设计方法

    设计和优化 mysql 表结构应从字段类型选择、主键与索引设计、冗余与范式处理、分表分区策略四个方面入手。1. 合理选择字段类型,如整数用 int/bigint,枚举值用 enum 或 tinyint,日期用 datetime,避免过度使用 text/blob;2. 主键建议使用自增整型,避免长字段…

    2026年9月24日
    1000
  • MySQL查询结果的排序和分页实现方法

    在mysql中,可以通过order by和limit关键字高效实现排序和分页。1.使用order by进行排序,支持升序和降序。2.使用limit和offset进行分页,控制返回结果的起始位置和数量。3.通过在排序列上创建索引,可以优化大数据集的查询性能。4.避免使用大offset值,改用主键或唯一…

    2026年9月24日
    100
  • mysql中如何排查磁盘空间不足问题

    先检查磁盘使用情况,使用df -h和du -sh定位大文件;再通过SQL查询分析数据库和表的空间占用;接着检查binlog、慢查询日志及临时文件;最后采取删除无用数据、归档、压缩、分区等措施释放空间并优化配置。 当MySQL出现磁盘空间不足时,可能会导致写入失败、服务中断甚至实例崩溃。排查这类问题需…

    2026年9月23日
    100
  • 如何在mysql中使用数值函数计算

    答案:MySQL数值函数用于执行数学运算,如ABS、ROUND、FLOOR、CEIL、MOD、POWER、SQRT等,可对数据直接计算。例如用ROUND四舍五入价格,TRUNCATE截断小数,FLOOR取整,MOD求余判断奇偶,SQRT开方,还可结合AVG、MAX等聚合函数使用,提升查询效率并减少应…

    2026年9月23日
    200
  • PHP同页面无限次表单提交与显示:防止数据覆盖的实现技巧

    本教程详细阐述了如何在php中实现同页面多次表单提交而不覆盖先前数据的方法。核心策略是利用html的数组命名输入(`name=”field[]”`)来收集多个值,并在每次页面刷新时,通过隐藏输入字段重新提交已有的数据,从而在不依赖数据库的情况下,实现“无限”次提交并显示所有历…

    2026年9月23日
    100
  • 如何在mysql中优化存储引擎参数

    优化MySQL存储引擎需根据业务场景调整参数。1. InnoDB:设innodb_buffer_pool_size为内存50%~70%,合理配置日志参数提升I/O性能,选用O_DIRECT减少缓存冲突,按磁盘性能设置io_capacity;2. MyISAM:分配足够key_buffer_size,…

    2026年9月23日
    100
  • 如何预防单点故障?VIP高可用搭建解决步骤

    如何预防单点故障?VIP高可用搭建解决步骤如何预防单点故障?VIP高可用搭建解决步骤如何预防单点故障?VIP高可用搭建解决步骤如何预防单点故障?VIP高可用搭建解决步骤

    单点故障是系统稳定性最大威胁,因为其一旦发生将导致服务瞬间瘫痪。解决核心在于消除“唯一”组件,通过构建高可用集群实现冗余备份。具体步骤包括:1. 使用虚拟ip(vip)配合keepalived工具实现自动漂移;2. 配置至少两台服务器组成集群并通过心跳机制监测状态;3. 设置track_script…

    2026年9月23日 • 用户投稿
    500

发表回复

登录后才能评论
关注微信