首页 > 数据库 >mysql事务隔离级别及实现原理,深度理解

mysql事务隔离级别及实现原理,深度理解

时间:2023-02-16 09:33:16浏览次数:38  
标签:lock 事务 快照 隔离 级别 提交 mysql 数据 id

1、事务是什么?

事务是数据库一个不可分的工作单元,可以将多个操作步骤表示为一个步骤。

2、事务的四大特性

Atomicity原子性, Consistency一致性,Isolation隔离性,Durability持久性

3、事务中出现的异常状况

脏读:一个事务读取到了另一个事务未提交的数据

时间  事务1  事务2
1   插入id=2数据
2  可以查询到id=2数据  
3   回滚事务,此时事务A查询到的id=2的数据就是脏数据

 

不可重复读

时间  事务1  事务2
1  查询id=2的数据,name值为张三  
2   update name=李四 where id=2
3   提交事务
4  查询id=2的数据,name值为李四  

 

幻读

当事务隔离级别为读已提交

时间  事务1  事务2
1  查询id>=1的数据,得到id为1,2的两条数据  
2   插入id=3,name=王五的数据
3   提交事务
4  再次查询id>=1的数据,得到id为1,2,3的三条数据  

 

当事务隔离级别为可重复读

时间  事务1  事务2
1  查询id>=1的数据,得到id为1,2的两条数据  
2   插入id=3,name=王五的数据
3   提交事务
4  执行 update tab set name = 王五1 where id = 3,此时update执行的是当前读,会更新id=3的快照数据  
5  再次查询id>=1的数据,得到id为1,2,3的三条数据  

 

4、锁介绍

  两阶段锁协议

    在InnoDB事务中,行锁是在用到的时候才加上的,但并不是不再用了就立刻释放,而是要等到事务commit或rollback才会释放

  锁的类型

    共享锁(shared lock)允许事务读一行数据

    排它锁(exclusive lock)允许事务删除或更新一行数据

  共享锁  排他锁
共享锁  兼容  不兼容
排它锁  不兼容  不兼容

  锁的算法

  行锁(record lock)针对单行记录的锁

  间隙锁(gap lock)锁定一个范围但不包含记录本身,注:在可重复读级别下存在

  间隙锁+行锁(Next-Key Lock)锁定一个范围并且包含记录本身,每个next-key lock都是前开后闭区间,假设数据库里有3条记录0,5,10 那么就有(-∞,0]、(0,5]、(5,10]、(10,+∞]4个可能的next-key lock,注:在可重复读、串行化级别下才存在

5、快照读与当前读

  多版本并发控制(MVCC):一行数据有多个版本,根据事务ID获取一致性读视图,数据版本相关内容维护在undo log里,注:在读已提交、可重复读级别下才存在,MVCC避免了锁的争抢,通过空间换时间保证了数据读取的正确性。

  快照读:读取的是快照数据,不保证是最新数据

  在读未提交、读已提交、可重复读隔离级别下,最普通的查询就是快照读

select * from table

  当前读:读到的数据是最新数据

-- 共享锁
select ... lock in share mode 
-- 排它锁
select ... for update 
insert ...
update ...
delete ...

6、事务隔离级别

  SQL标准定义了四个隔离级别

  • 读未提交(READ UNCOMMITED)

     特点:读的时候未对数据加锁,修改数据的时候对数据添加行级共享锁

          效果:因为修改数据时候添加的是共享锁,所以会被其他事务读到,产生脏读的问题

 

  • 读已提交(READ COMMIED)

      特点:(快照读)读的时候会通过MVCC的一致性视图读到最新的、已提交事务的数据版本

      效果:(快照读)因为通过MVCC读取的是已提交事务的数据版本,所以不会存在脏读。通过MVCC读到的数据,没有进行加锁操作, 所以其他事务仍然可以对读到的数据进行修改并提交,这时候再次读取就发生了不可重复读。

(当前读)通过显示加锁,防止了其他事务对其行数据的修改,从而避免了不可重复读

  • 可重复读(REPEATABLE READ)

     特点:(快照读)读的时候会通过MVCC的一致性视图读到开启事务时刻、已提交事务的最新数据版本

     效果:(快照读)因为通过MVCC读取的是开启事务时刻,已提交事务的数据版本,所以无论其他事务怎么修改,看到的数据都是雷打不动的固定的数据版本,这时候再次读取就避免了不可重复读。因为在修改数据的时候使用了next-key lock,所以即使进行插入操作也会被锁阻塞,这样也避免了幻读情况的产生。在实际情况中,锁的算法比较灵活 ,根据sql语句的不同,和命中索引的区别,即有next-key lock+gap lock锁住更大范围的情况,也有在唯一索引场景 next-key lock退化成 record lock以及gap lock的情况

  • 串行化(SERIALIZABLE)
  脏读  不可重复读  幻读
读未提交  未解决  未解决  未解决
读已提交  已解决  快照读未解决,可通过加锁解决  未解决
可重复读  已解决  已解决  MVCC能解决部分场景
串行化  已解决  已解决  已解决

  

 

标签:lock,事务,快照,隔离,级别,提交,mysql,数据,id
From: https://www.cnblogs.com/yulongzhang/p/17105489.html

相关文章

  • 解决mysqlclient安装报缺少Microsoft Visual C++ 14.0 is required
    安装mysqlclient报错error:MicrosoftVisualC++14.0isrequired.Getitwith“MicrosoftVisualC++BuildTools”1.不要去下载VisualStudio!!!==没什么用(对我而言)......
  • 2.mysql存储过程、存储函数与触发器
    --创建一个存储过程DELIMITER$CREATEPROCEDURE存储过程名称(返回类型参数名1参数类型1,....)[......]BEGIN--具体组成存储过程的SQL语句....END$DE......
  • 1.mysql创建索引
    --创建一个普通索引(方式①)createindex索引名ON表名(列名(索引键长度)[ASC|DESC]);--创建一个普通索引(方式②)altertable表名addindex索引名(列名(索引键长度)......
  • mysql keepalive +双主架构注意问题
    具体搭建参考Linux两节点+keepalive搭建MySQL双主集群-So怪咖-博客园(cnblogs.com)auto_increment_offset=1#双主复制中,2台服务器的自增长字段初值分别配置为1......
  • mysql 实现insert update 功能
    <insertid="insertOrUpdateSelective"keyColumn="id"keyProperty="id"parameterType="com.xxx.xxx.UserDO"useGeneratedKeys="true">INSERTINTOuser<tr......
  • 使用mysql管理软件导入恢复/导出备份mysql
    利用mysql管理工具导入导出,可以避免数据导入导出时出现的乱码问题,mysql的管理软件有很多,文本主要介绍NavicatPremium的使用方法,软件可以去官方搜索下载。本文来源于互联网......
  • mysql的性能的一些测试
    测试平台mysql8.0.31,2核心4线内存2G的虚拟机硬盘ssd,下面测试结果的瓶颈很多都来自这2G的内存。char比verchar块?首先说结论,差不多,没区别,别信谣110W数据,无......
  • 免安装MYSQL下载并安装
    一、去MYSQL官网下载https://www.mysql.com/官网首页翻到下面,点击如图所示的MySQLCommunityServer  二、解压,配置,安装可以看这篇教程:http://c.biancheng.net/vi......
  • 部署canal同步mysql-binlog到kafka具体操作
    准备[mysqld]log-bin=mysql-bin#开启binlogbinlog-format=ROW#选择ROW模式授权canal链接MySQL账号具有作为MySQLslave的权限CREATEUSERcanalIDENTI......
  • mysql数据库备份
    完全备份每次对数据进行完整的备份可以备份整个数据库,包含用户表、系统表、索引、视图和存储过程等所有数据库对象但它需要花费更多的时间和空间,所以,做一次完全备份的......