• MySQL: 幻读演示 & 解决幻读问题


    幻读: select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。

    幻读演示

    1. 打开 A B 窗口, 选择数据库 开启事务

    2. A 窗口 先执行一次查询操作

    -- 假设要再添加一条id为3的 数据,在添加之前先判断是否存在 
    select * from account where id = 3;

    3. B 窗口 插入一条数据 提交事务

    INSERT INTO account VALUES(3,'lucy',1000); 
    commit;

    4.  A 窗口执行 插入操作, 发现报错. 出现幻读

     A窗口:“见鬼了,我刚才读到的结果应该可以支持我这样操作才对啊,为什么现在不可以”

    解决幻读问题

    将事务隔离级别设置到最高 SERIALIZABLE ,以挡住幻读的发生

    如果一个事务,使用了SERIALIZABLE——可串行化隔离级别时,在这个事务没有被提交之前 ,

    其 他的线程,只能等到当前操作完成之后,才能进行操作,这样会非常耗时,

    而且会影响数据库的 性能,数据库不会使用这种隔离级别

    代码示例:

    1. 恢复数据

    DELETE FROM account WHERE id = 3;

    2. 打开A 窗口 将数据隔离级别提升到最高

    set global transaction isolation level SERIALIZABLE;

    3.  打开 A B 窗口, 选择数据库 开启事务

    4. A 窗口 先执行一次查询操作

    SELECT * FROM account WHERE id = 3;

    5. B 窗口插入一条数据

    INSERT INTO account VALUES(3,'lucy',1000);

     6. A 窗口执行插入操作, 提交事务数据插入成功.

    INSERT INTO account VALUES(3,'lucy',1000);
    commit;

    7. B 窗口在 A窗口提交事务之后, 再执行,但是主键冲突出现错误

    总结:

      serializable 串行化可以彻底解决幻读,但是 事务只能排队执行,严重影响效率, 数据库不会使用这种隔离级别

    MySQL单表,约束和事务 - 练习

     

     

     

     

     

  • 相关阅读:
    druid-1.0.13 数据库配置文件密码加密
    PostConstruct注解
    easyui formatter 返回easyui组件
    小师妹问 easyUI mergeCells 行合并后表头和内容对不齐
    Java Split以竖线作为分隔符
    Integer比较值的时候小心使用
    js 关键字 in
    Asp.net中防止用户多次登录的方法
    C#取得站点跟目录
    解读支付宝接口实现步骤
  • 原文地址:https://www.cnblogs.com/JasperZhao/p/15014224.html
Copyright © 2020-2023  润新知