zoukankan      html  css  js  c++  java
  • 【holm】MySQL事务隔离级别以及并发情况下出现的常见问题

    总览

    MySQL事务隔离级别

    • read uncommitted 读取未提交的数据
    • read committed 读取提交的数据
    • repeatable read 可重复读
    • serializable 串行化

    常见问题

    • 更新丢失————事务A的操作被事务B覆盖
    • 脏读————事务A读取了事务B已经修改但尚未提交的数据,若事务B回滚,则事务A读取到的数据为脏数据
    • 不可重复读————事务A执行操作时两次读取数据不一致
    • 幻读————再解决不可重复读问题的基础上,可能无法根据查询到的值进行修改表数据。例如事务A无法插入一条自己事务内查询不到但事务B已经插入的相同数据,原因是事务B在事务A开始之后进行的插入...

    MySQL相关操作

    • MySQL之后隔离级别的关键字为transaction_isolation
    • MySQL8之前隔离级别的关键为tx_isolation
    • 隔离级别的作用范围有GLOBALSESSION

    查看隔离级别

    • show [GLOBAL|SESSION] VARIABLES like 'transaction_isolation'
    • SElECT @@transation_isolation

    设置隔离级别

    • SET [SESSION|GLOBAL] transaction_isolation=[0|1|2|3]

    read uncommitted

    • 此隔离级别中,所有事务都可以看到其他未提交事务的执行结果。(很少使用,舍弃了所有安全性的同时并没有明显性能提升)

    问题:出现脏数据

    read committed

    • 此隔离级别中,一个事务只能看见已提交事务所做的改变。

    问题:不可重复读

    repeatable read

    • MySQL默认的事务隔离级别
    • 此隔离级别可以确保同一事务内相同的查询语句执行结果一致

    问题:幻读

    实例:

    -- 事务一
    BEGIN;
    SELECT * FROM table00;
    /*
    查询结果:
    |id|name|
    |-|-|
    |1|wu|
    */
    
    -- 此时系统遇到并发,首先执行完事务二
    
    INSERT INTO table00 VALUES(2,"we"); -- 执行失败
    
    SELECT * FROM table00;
    /*
    查询结果不变:(可重复读但出现幻觉——明明不存在却无法插入)
    |id|name|
    |-|-|
    |1|wu|
    */
    
    COMMIT;
    
    -- 事务二
    BEGIN;
    SELECT * FROM table00;
    /*
    查询结果:
    |id|name|
    |-|-|
    |1|wu|
    */
    INSERT INTO table00 VALUES(2,"we"); -- 插入
    SELECT * FROM table00;
    /*
    查询结果: (成功插入)
    |id|name|
    |-|-|
    |1|wu|
    |2|we|
    */
    COMMIT;
    

    避免幻读

    • 乐观锁为理论基础的MVCC(多版本并发控制)
    • 间隙锁

    serializable

    这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突。换言之,它会在每条select语句后自动加上lock in share mode,为每个查询操作施加一个共享锁。在这个级别,可能导致大量的锁等待现象。该隔离级别主要用于InnoDB存储引擎的分布式事务。

    隔离级别的选择(注意这部分是纸上谈兵,算是学习到现在的个人见解和猜测吧)

    • 并发量很少的情况下可以考虑选择串行化级别,一般来说面向用户尽可能不用此隔离级别。
    • 接着就是使用用户体验较好的乐观锁
    • 在高并发情况下增加消息队列对大量请求进行处理

    参考资料

    • mysql doc
    • 数据库应用设计课程资料
  • 相关阅读:
    WinDbg调试C#技巧,解决CPU过高、死锁、内存爆满
    Window环境下搭建Git服务器
    Virtual Box虚拟机Ubuntu系统安装及基本配置
    修改VS2017新建类模板文件添加注释
    .net core 使用IIS作为宿主Web服务器,部署常见问题
    Asp.Net进程外Session(状态服务器Session、数据库Session)
    百度地图DEMO-路线导航,测距,标点
    c#文件图片操作
    C#代码安装Windows服务(控制台应用集成Windows服务)
    通过经纬度获取地址信息
  • 原文地址:https://www.cnblogs.com/holm/p/12870737.html
Copyright © 2011-2022 走看看