事务

作者: kar_joe | 来源:发表于2020-01-27 21:36 被阅读0次

    事务基本概念

    事务特性

    ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔离性、持久性)

    问题

    脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)

    隔离级别

    • 读未提交是指,一个事务还没提交时,它做的变更就能被别的事务看到。
    • 读提交是指,一个事务提交之后,它做的变更才会被其他事务看到。
    • 可重复读是指,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
    • 串行化,顾名思义是对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。


      image.png

      在不同隔离级别下,V1、V2、V3分别是多少

    事务隔离的实现

    在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。
    通过多版本并发控制MVCC实现


    image.png

    通过undolog,可以实现获取指定版本的数据。InnoDB 利用了“所有数据都有多个版本”的这个特性,实现了“秒级创建快照”的能力。

    为什么尽量不要使用长事务。
    长事务意味着系统里面会存在很老的事务视图。由于这些事务随时可能访问数据库里面的任何数据,所以这个事务提交之前,数据库里面它可能用到的回滚记录都必须保留,这就会导致大量占用存储空间;又因为指定版本的数据,是通过最新版本然后倒序执行所有undolog获取到的,所以长事务的select语句可能耗时很久

    举例1

    可重复读隔离级别


    image.png
    image.png

    一个数据版本,对于一个事务视图来说,除了自己的更新总是可见以外,有三种情况:

    • 版本未提交,不可见;
    • 版本已提交,但是是在视图创建后提交的,不可见;
    • 版本已提交,而且是在视图创建前提交的,可见。

    若改为当前读


    image.png

    更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。select 语句如果加锁,也是当前读。所以,如果把事务 A 的查询语句 select * from t where id=1 修改一下,加上 lock in share mode 或 for update。

    假设事务 C 不是马上提交的,而是变成了下面的事务 C’,会怎么样呢


    image.png

    事务 C’没提交,也就是说 (1,2) 这个版本上的写锁还没释放。而事务 B 是当前读,必须要读最新版本,而且必须加锁,因此就被阻塞了,必须等到事务 C’释放这个锁,才能继续它的当前读。

    假如隔离级别是读提交,A读到的又是什么呢?

    举例2

    当前库存:num=200
    假如多线程并发,AB同时开启事务,A先请求到行锁,
    A:
    start transaction;
    select num from t where num>0;先查询当前库存值(num>0)
    update t set num=num-200; 库存减量

    B:
    start transaction;
    select num from t where num>0;先查询当前库存值(num>0)
    update t set num=num-200; 库存减量
    ----结果---
    A:查询到num=200,做了库存减量成了0
    B:事务启动后,查询到也是200,等 A 释放了行锁,B进行update,直接变成 -200
    但是 B 查询时,时有库存的,因此才减库存,结果变成负的。

    1. 问题分析
      问题主要是快照读与当前读数据不一致导致的

    2. 如何解决
      查询采用当前读;或者更新时加where条件,要求库存大于200

    相关文章

      网友评论

          本文标题:事务

          本文链接:https://www.haomeiwen.com/subject/idwethtx.html