• 技术文章 >数据库 >mysql教程

    mysql事务隔离级别有哪些

    青灯夜游青灯夜游2023-01-04 16:37:59原创85

    事务隔离级别有四个:1、Read Uncommitted(读取未提交),允许读取尚未提交的数据变更,可能造成脏读、不可重复读、幻读。2、Read Committed(读取已提交),允许读取并发事务已经提交的数据,可以避免脏读,但是可能造成不可重复、幻读。3、Repeatable Read(可重复读取),对同一字段多次读取的结果都是一致。4、Serializable(可串行化)。

    本教程操作环境:windows7系统、mysql8版本、Dell G3电脑。

    一、什么是事务?

    事务是逻辑上的一组操作,要么全执行,要么全不执行。

    事务最经典栗子也经常被拿出来的栗子就是银行转账了。比如小明要给小红转账1000元,这个转账会涉及到两个关键操作:将小明的余额减1000元,将小红的余额减1000元。万一这两个操作之间突然出现错误,导致小明余额减少但是小红余额没有增加,这种情况是肯定不允许的。事务就是保证这两个关键操作要么都成功,要么都不成功。

    二、事务的特性(ACID)

    三、并发事务带来的问题

    在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务(多个用户对同一数据进行操作)。并发虽然是必须的,但是可能会带来以下的问题:

    不可重复读和幻读区别:

    不可重复读的重点是修改,幻读的重点是新增或者删除。

    栗子1(同样的条件,你读取过的数据,再次读取的时候不一样了):事务1中的A先生读取自己的工资是1000的操作还没结束,事务2的B先生就修改了A先生的工资为2000,A先生再次读取自己工资的时候就变成2000了,这就是不可重复读。

    栗子2(同样的条件,第1次和第2次读取出来的记录条数不一样):假如某工资表中工资大于3000的有4人,事务1读取了所有工资大于3000的人,总共查询到4条记录,这是事务2又查询了一条工资大于3000的记录,事务1再次读取查询到的记录就是5条了,这就是幻读。

    四、事务隔离级别

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

    隔离级别脏读不可重复读幻读
    读取未提交
    读取已提交×
    可重复读××
    可串行化×××

    MySQL InnoDB存储引擎默认的事务隔离级别是可重复读(REPEATABLE-READ),可以通过命令select @@tx_isolation;语句来查看,MySQL 8.0 该语句改为SELECT @@transaction_isolation;

    mysql> SELECT @@tx_isolation;
    +-----------------+
    | @@tx_isolation  |
    +-----------------+
    | REPEATABLE-READ |
    +-----------------+

    MySQL InnoDB存储引擎的可重复读并不能避免幻读,需要应用使用加锁读来保证,这加锁读使用到的机制就是Next-Key Locks

    因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是读取已提交(READ-COMMITTED)InnoDB 存储引擎默认使用 REPEATABLE-READ(可重读) 并不会有任何性能损失。

    InnoDB存储引擎在分布式事务的情况下一般会用到可串行化隔离级别。

    ? 拓展一下(以下内容摘自《MySQL 技术内幕:InnoDB 存储引擎(第 2 版)》7.7 章):

    InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与到一个全局的事务中。事务资源通常是关系型数据库系统,但也可以是其他类型的资源。全局事务要求在其中的所有参与的事务要么都提交,要么都回滚,这对事务的原有ACID要求又有了提高。另外,在使用分布式事务时,InnoDB 存储引擎的事务隔离级别必须设置为 SERIALIZABLE。

    四、实际情况演示

    MySQL命令行的默认配置中事务都是自动提交的,即执行SQL语句就会马上执行COMMIT操作。可以用命令START TRANSACTION开始一个事务。

    我们可以通过下面命令设置事务隔离级别。

    SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]

    我们再来看一下我们在实际操作中使用到的一些并发控制语句:

    (脏读)读取未提交

    (避免脏读)读取已提交

    不可重复读

    还是刚才上面的读已提交的图,虽然避免了读未提交,但是却出现了,一个事务还没有结束,就发生了 不可重复读问题。

    可重复读

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysjbfC4b-1651149978452)(https://qtspace.cn/contentimg/81.jpg)]

    幻读

    演示幻读出现的情况

    sql 脚本 1 在第一次查询工资为 500 的记录时只有一条,sql 脚本 2 插入了一条工资为 500 的记录,提交之后;sql 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。

    幻读和不可重复读有些相似之处 ,但是不可重复读的重点是修改,幻读的重点在于新增或者删除。

    解决幻读的方法

    说明:Next-Key Locks 相当于 行锁 + 间隙锁

    【相关推荐:mysql视频教程

    以上就是mysql事务隔离级别有哪些的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:事务隔离 mysql
    上一篇:聊聊怎么用MySQL快速实现一个推荐算法 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • MySQL单表查询进阶总结• 一起聊聊Mysql两阶段锁和死锁• PHP与MySQL连接的方法总结• 一文聊聊MySQL中的插入意向锁• 创建MySQL索引大幅优化某PHP应用性能• 聊聊怎么用MySQL快速实现一个推荐算法
    1/1

    PHP中文网