• 事务并发问题和隔离级别


    事务基本性质

    事务有四个属性,ACID。

    • 原子性Atomicity,事务里的命令全部执行,或全部不执行,是不可分割的整体。
    • 一致性Consistency,保证操作前后数据和数据结构的一致性。
    • 隔离性Isolation,不同事物之间互补干扰。同一时间只允许一个事务请求一个数据。
    • 持久性Durability,数据更新持久化,更改时永久的。

    事务的并发问题

    事务并发会造成三个问题:脏读,不可重复读,幻读。

    1. 脏读:事务A读了事务B更新的数据,然后事务B回滚撤销了,事务A读取的数据就是脏读。
    2. 不可重复读:事务A读取数据num后,事务B对其修改,事务A再次读取数据num,前后不一致,这情况为不可重复读。
    3. 幻读:事务A读取数据(一张表),事务B对此表新增或删除记录,这种情况为幻读。

    不可重复读和幻读的区别:一个针对一条记录的更新,一个针对表的更新。因此要解决两者,分别要用到行锁和表锁。这也就造成解决两者的隔离级别不同。

    事务隔离级别

    隔离级别有四个:

    1. read-uncommitted:不能解决脏读、不可重复读、幻读
    2. read-committed:解决脏读,不能解决不可重复读、幻读
    3. repeatable-read:解决脏读、不可重复读、幻读
    4. serializable:解决脏读、不可重复读、幻读

    其中mysql的事务隔离级别为reapeatable-read
    image

    事务隔离级别四个例子

    打开两个mysql进程,创建一个test表,插入简单的数据,可以在两个mysql进程都看到表内容。
    image
    image

    read-uncommitted

    两个进程mysql都要将隔离级别设置为read-uncommitted。
    image

    步骤:

    • 进程A开启事务读数据num为50
    • 进程B开启事务读数据num为50,修改数据为100
    • 进程A再次读数据为100
    • 进程B回滚,则进程A读取到的数据100为脏数据

    进程B的情况
    image

    read-committed

    步骤:

    • 进程A开启事务读数据num为50
    • 进程B开启事务读数据num为50,修改数据为100
    • 进程A读数据num仍然为50,并没有受到进程B事务的影响
    • 进程B提交事务,读取数据为100
    • 进程A读取数据num为100,则出现数据不可重复读现象
      image

    repeatable-read

    步骤:

    • 进程A开启事务读取数据num为50
    • 进程B开启事务读取数据num为50,修改数据为100
    • 进程B提交事务,读取数据num为100
    • 进程A读取数据num仍然为50,即使进程B已经提交事务,进程A并没有受到进程B的影响
    • 进程B插入一条数据
    • 进程A没有查出新增数据,没有数据幻读
    • 进程A提交事务后,查询数据num为100,并查询到新增数据
      image

    serializable

    步骤:

    • 进程A开启事务读取数据为100
    • 进程B开启事务读取数据为100,修改数据为50,进程B卡住

    个人认为,是因为表被锁了,在等待进程A释放锁,然后进程B可以对表进行修改

    小结

    • 事务隔离级别为read-committed时,写数据会锁住相应行,进程A再读时,就会读取上个版本的数据,但是会增加或删除别的记录,就会出现幻读现象。
    • 事务隔离为repeatable-read时,更新数据会锁住整张表,从而防止幻读现象。
    • 事务隔离级别为串行化时,读写数据都会锁住整张表。

    在进行相关操作后,对事务的理解更加深刻。关于读取上版本,MVCC内容需要抽空去学习一下。

  • 相关阅读:
    DevExpress GridControl用法----SearchLookUpEdit,单选框,图片,颜色,进度条,分页查询
    EasyUi之Datagrid行拖放冲突处理
    [LeetCode No.1] 两数之和
    [LeetCode No.2] 两数相加
    注册定义文件扩展名图标和关联相应的应用程序
    加载进度-【圆圈+百分比】
    .net core + eureka + spring boot 服务注册与调用
    一个Java类的加载
    Nifi:nifi内置处理器Processor的开发
    Nifi:nifi的基本使用
  • 原文地址:https://www.cnblogs.com/chenshaowei/p/12566030.html
Copyright © 2020-2023  润新知