当前位置: 首页 > news >正文

网站建设亿金手指花总14上海外贸网站seo

网站建设亿金手指花总14,上海外贸网站seo,石家庄大型公司建站,belton wordpress事务隔离级别是怎么实现的? 四种隔离级别具体的实现方式 对于「读未提交」:直接读取最新的数据就好。对于「串行化」:通过加读写锁的方式来避免并行访问。对于「读提交」和「可重复读」:通过 Read View 来实现,主要区…

事务隔离级别是怎么实现的?

四种隔离级别具体的实现方式

  • 对于「读未提交」:直接读取最新的数据就好。
  • 对于「串行化」:通过加读写锁的方式来避免并行访问。
  • 对于「读提交」和「可重复读」:通过 Read View 来实现,主要区别在于创建 Read View 的时机不同。
    • 可以把 Read View 理解成一个数据快照,「读提交」隔离级别是在「每个语句执行前」都会重新生成一个 Read View,而「可重复读」隔离级别是「启动事务时」生成一个 Read View,然后整个事务期间都在用这个 Read View。

事务的特性

  • 并不是所有的引擎都能支持事务,比如 MySQL 原生的 MyISAM 引擎就不支持事务,也正是这样,所以大多数 MySQL 的引擎都是用 InnoDB。
  • 事务的特性
    • 原子性(Atomicity)同一个事务中的所有操作,要么全部完成,要么全部回滚,就像这个事务从来没有执行过一样,就好比买一件商品,购买成功时,则给商家付了钱,商品到手;购买失败时,则商品在商家手中,消费者的钱也没花出去。
    • 一致性(Consistency)是指事务操作前后,数据满足完整性约束,数据保持合法状态。比如,用户 A 和用户 B 在银行分别有 800 元和 600 元,总共 1400 元,用户 A 给用户 B 转账 200 元,分为两个步骤,从 A 的账户扣除 200 元和对 B 的账户增加 200 元。一致性就是要求上述步骤操作后,最后的结果是用户 A 还有 600 元,用户 B 有 800 元,总共 1400 元,保持数据的合法状态。
    • 隔离性(Isolation):多个事务同时使用相同的数据时,不会相互干扰,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致,因为每个事务都有一个完整的数据空间,对其他并发事务是隔离的。也就是说,消费者购买商品这个事务,是不影响其他消费者购买的。
    • 持久性(Durability):事务一旦提交,对数据的修改就是永久的。
  • InnoDB 引擎通过什么技术来保证事务的这四个特性的呢?
    • 持久性是通过 redo log (重做日志)来保证的;
    • 原子性是通过 undo log(回滚日志) 来保证的;
    • 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
    • 一致性则是通过持久性+原子性+隔离性来保证;

并行事务会引发什么问题?

MySQL 服务端是允许多个客户端连接的,在同时处理多个事务的时候,就可能出现**脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)**的问题。

  • 脏读:一个事务读取到了另一个事务修改过的但是还未提交的数据,就发生了脏读。此时事务发生回滚,那么另一个事务刚才得到的数据就是过期的数据。
  • 不可重复读:一个事务内多次读取同一个数据,如果出现前后两次读到数据不一样的情况,就意为着发生了不可重复读现象。
  • 幻读:一个事务内多次查询某个符合查询条件的记录数量,如果出现前后两次查询到的记录数量不一样的情况,就意味着发生了幻读现象。

事务的隔离级别有哪些?

SQL 标准提出了四种隔离级别来规避这些现象,隔离级别越高,性能效率就越低,这四个隔离级别如下:

  • (可以)读未提交(read uncommitted,指一个事务还没提交时,它做的变更就能被其他事务看到;
  • 读已提交RC(read committed,指一个事务提交之后,它做的变更才能被其他事务看到;
  • 可重复读RR(repeatable read,指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,MySQL InnoDB 引擎的默认隔离级别
  • 串行化(serializable;会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行;

针对不同的隔离级别,并发事务发生的现象有可能不同。

  • 在「读未提交」隔离级别下,可能发生脏读、不可重复读和幻读现象;
  • 在「读提交」隔离级别下,可能发生不可重复读和幻读现象,但是不可能发生脏读现象;
  • 在「可重复读」隔离级别下,可能发生幻读现象,但是不可能脏读和不可重复读现象;
  • 在「串行化」隔离级别下,脏读、不可重复读和幻读现象都不可能会发生。

MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象

  • 在可重复读隔离级别中,普通的 select 语句就是基于 MVCC 实现的快照读,也就是不会加锁的。而 select … for update 语句是当前读,也就是每次读都是拿到最新版本的数据,但是它会对读到的记录加上 next-key lock 锁。

    • 快照读(普通 select 语句),是通过 **MVCC(多版本控制)方式解决了幻读。**因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。

    • 当前读(select … for update 等语句),是**通过 next-key lock(记录锁+间隙锁)方式解决了幻读。**因为当执行 select … for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。


MySQL 有两种开启事务的命令,分别是:

  • 第一种:begin/start transaction 命令;当执行了增删查改操作的 SQL 语句,才是事务真正启动的时机。
  • 第二种:start transaction with consistent snapshot 命令;马上启动事务。

Read View在MVCC里如何工作?

Read View 有四个重要的字段:

  • creator_trx_id :指的是创建该 Read View 的事务的事务 id

  • m_ids :指的是在创建 Read View 时,当前数据库中「活跃事务」的事务 id 列表,注意是一个列表,“活跃事务”指的就是,启动了但还没提交的事务

  • min_trx_id :指的是在创建 Read View 时,当前数据库中「活跃事务」中事务 id 最小的事务,也就是 m_ids 的最小值。

  • max_trx_id :这个并不是 m_ids 的最大值,而是创建 Read View 时当前数据库中应该给下一个事务的 id 值,也就是全局事务中最大的事务 id 值 + 1;


聚簇索引记录中有两个隐藏列:

  • trx_id,当一个事务对某条聚簇索引记录进行改动时,就会把该事务的事务 id 记录在 trx_id 隐藏列里

  • roll_pointer,每次对某条聚簇索引记录进行改动时,都会把旧版本的记录写入到 undo 日志中,然后这个隐藏列是个指针,指向每一个旧版本记录,于是就可以通过它找到修改前的记录。

  • 在创建 Read View 后,我们可以将记录中的 trx_id 划分这三种情况:

在这里插入图片描述

  • 一个事务去访问记录的时候,除了自己的更新记录总是可见之外,还有这几种情况:

    • 如果记录的 trx_id 值小于(当前事务的)Read View中的 min_trx_id 值(活跃事务中的最小事务id),表示这个版本的记录是在创建 Read View 已经提交的事务生成的,所以该版本的记录对当前事务可见
    • 如果记录的 trx_id 值大于等于(当前事务的)Read View中的 max_trx_id 值(全局事务的最大id + 1),表示这个版本的记录是在创建 Read View 才启动的事务生成的,所以该版本的记录对当前事务不可见
    • 如果记录的 trx_id 值在 Read View 的min_trx_id和max_trx_id之间,需要判断 trx_id 是否在 m_ids 列表中(也就是判断当前事务是否为活跃事务/未提交事务):
      • 如果记录的 trx_id m_ids 列表中,表示生成该版本记录的活跃事务依然活跃着(活跃事务还没提交),所以该版本的记录对当前事务不可见
      • 如果记录的 trx_id 不在 m_ids列表中,表示生成该版本记录的活跃事务已经被提交,所以该版本的记录对当前事务可见
  • 这种通过「版本链」来控制并发事务访问同一个记录时的行为就叫 MVCC(多版本并发控制),使数据库在发生读写请求冲突时不用加锁,这里的读指的是快照读,这样就提高了MySQL的并发性能。

可重复读是如何工作的?

  • 可重复读隔离级别是启动事务时生成一个 Read View,然后整个事务期间都在用这个 Read View

  • 假设事务 A (事务 id 为51)启动后,紧接着事务 B (事务 id 为52)也启动了,那这两个事务创建的 Read View 如下:

  • 接着,在可重复读隔离级别下,事务 A 和事务 B 按顺序执行了以下操作:

    • 事务 B 读取小林的账户余额记录,读到余额是 100 万;

      • 找到记录后,会先看这条记录的 trx_id,此时发现 trx_id 为 50,比事务 B 的 Read View 中的 min_trx_id 值(51,最小活跃事务id)还小,这意味着修改这条记录的事务早就在事务 B 启动前提交过了,所以该版本的记录对事务 B 可见的,也就是事务 B 可以获取到这条记录。
    • 事务 A 将小林的账户余额记录修改成 200 万,并没有提交事务;

      • 事务 A 通过 update 语句将这条记录修改了(还未提交事务),将小林的余额改成 200 万,这时 MySQL 会记录相应的 undo log,并以链表的方式串联起来,形成版本链在这里插入图片描述
    • 事务 B 读取小林的账户余额记录,读到余额还是 100 万;

      • 事务 B 第二次去读取该记录,发现这条记录的 trx_id 值为 51,在事务 B 的 Read View 的 min_trx_id 和 max_trx_id 之间,则需要判断 trx_id 值是否在 m_ids 范围内,判断的结果是在的,那么说明这条记录是被还未提交的事务修改的,这时事务 B 并不会读取这个版本的记录。而是沿着 undo log 链条往下找旧版本的记录,直到找到 trx_id 小于事务 B 的 Read View 中的 min_trx_id 值的第一条记录,所以事务 B 能读取到的是 trx_id 为 50 的记录,也就是小林余额是 100 万的这条记录。这里就通过MVCC的方式实现了可重复读。因为都是快照读(普通SELECT语句),所以MVCC也解决了幻读。
    • 事务 A 提交事务;

    • 事务 B 读取小林的账户余额记录,读到余额依然还是 100 万;

      • 当事物 A 提交事务后,由于隔离级别是可重复读,所以事务 B 再次读取记录时,还是基于启动事务时创建的 Read View 来判断当前版本的记录是否可见。所以,即使事物 A 将小林余额修改为 200 万并提交了事务, 事务 B 第三次读取记录时,读到的记录都是小林余额是 100 万的这条记录。

读提交是如何工作的?

  • 读提交隔离级别是在每次读取数据时,都会生成一个新的 Read View

  • 假设事务 A (事务 id 为51)启动后,紧接着事务 B (事务 id 为52)也启动了,接着按顺序执行了以下操作:

    • 事务 B 读取数据(创建 Read View),小林的账户余额为 100 万;

      • 找到记录后,会先看这条记录的 trx_id,此时发现 trx_id 为 50,比事务 B 的 Read View 中的 min_trx_id 值(51,最小活跃事务id)还小,这意味着修改这条记录的事务早就在事务 B 启动前提交过了,所以该版本的记录对事务 B 可见的,也就是事务 B 可以获取到这条记录。

        在这里插入图片描述

    • 事务 A 修改数据(还没提交事务),将小林的账户余额从 100 万修改成了 200 万;

    • 事务 B 读取数据(创建 Read View),小林的账户余额为 100 万;

      • 事务 B 在找到小林这条记录时,会看这条记录的 trx_id 是 51,在事务 B 的 Read View 的 min_trx_id 和 max_trx_id 之间,接下来需要判断 trx_id 值是否在 m_ids 范围内,判断的结果是在的,那么说明这条记录是被还未提交的事务修改的,这时事务 B 并不会读取这个版本的记录。而是,沿着 undo log 链条往下找旧版本的记录,直到找到 trx_id 「小于」事务 B 的 Read View 中的 min_trx_id 值的第一条记录,所以事务 B 能读取到的是 trx_id 为 50 的记录,也就是小林余额是 100 万的这条记录。
    • 事务 A 提交事务;

    • 事务 B 读取数据(创建 Read View),小林的账户余额为 200 万;

      • 第三次创建的Read View(m_ids变为只有52,因为A事务id为51的已经提交了,min_trx_id变为52。):事务 B 在找到小林这条记录时,会发现这条记录的 trx_id 是 51,比事务 B 的 Read View 中的 min_trx_id 值(52,最小活跃事务id)还小,这意味着修改这条记录的事务早就在创建 Read View 前提交过了,所以该版本的记录对事务 B 是可见的在这里插入图片描述
  • 正是因为在读提交隔离级别下,事务每次读数据时都重新创建 Read View,那么在事务期间的多次读取同一条数据,前后两次读的数据可能会出现不一致,因为可能这期间另外一个事务修改了该记录,并提交了事务。

http://www.qdjiajiao.com/news/2190.html

相关文章:

  • 做网站项目主要技术网上商城推广13种方法
  • 上海建科建设监理网站国际新闻头条
  • 网站推荐入口最强大的搜索引擎
  • seo网站推广策略万网app下载
  • 湖北什么网站建设值得推荐网站设计与建设
  • 用网站做平台有哪些志鸿优化网下载
  • 要找人做公司网站应该怎么做百度关键词热度排名
  • 上海自主建站模板搜索引擎优化哪些方面
  • 沈阳网站制作服务站长之家的seo综合查询工具
  • 北京学网站开发网站源码交易平台
  • 网站开发的目的意义特色创新湖南专业seo推广
  • 网站建设公司销售求几个微信推广平台
  • 营销型网站建设排名浏览器大全网站
  • 自己做网站怎么挣钱餐饮管理培训课程
  • 那些网站企业可以免费展示百度明星人气榜入口
  • 网站建设 搜狐号引流推广网站平台
  • 济南做网站互联网公司长春刚刚最新消息今天
  • axure做的是静态网站品牌营销包括哪些方面
  • 今日国内重大新闻seo推广和百度推广的区别
  • 迅速编程做网站百青藤广告联盟
  • 有做酒席酒水网站吗如何自己创造一个网站平台
  • 连云港企业网站建设公司360网址大全
  • 网站目录结构 权限长沙seo外包平台
  • 怎样设计app软件百度关键词搜索优化
  • 苏州教育学会网站建设今日国际重大新闻
  • 网站建设个人兼职房产网站建设
  • 免费下ppt课件的网站友谊平台
  • 嘉兴免费网站建站模板网络推广方式方法
  • 网站建设提成互联网项目推广平台有哪些
  • 南京h5网站开发短视频推广平台有哪些