前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >事务和MySQL隔离级别

事务和MySQL隔离级别

作者头像
_春华秋实
修改2023-09-03 09:59:46
5290
修改2023-09-03 09:59:46
举报
文章被收录于专栏:_春华秋实_春华秋实

数据库存储引擎

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。

MySQL中MyISAM与InnoDB的区别

  • InnoDB支持事务,MyISAM不支持事务。
  • InnoDB支持行级锁,MyISAM支持表级锁。
  • InnoDB支持MVCC, MyISAM不支持。
  • InnoDB不支持全文索引,MyISAM支持。

通过以上区别总结出:

InnoDB: 数据可靠性要求比较高,支持事务,适合表更新和查询比较频繁的场景

MyISAM:适合插入不频繁,查询频繁的场景

数据库ACID

为了保证数据库事务的正确性提出来的一个理论

  1. 原子性(Atomicity):事务中的操作是一个不可分割的整体单元,要么全部都做,要么全部不做。
  2. 一致性(Consistency):数据库总是从一个一致性的状态转换到另一个一致性的状态
  3. 隔离性(Isolation):事务的结果只有提交了其他事务才可见
  4. 持久性(Durability):一旦事务提交完成,修改就是永久的,即使服务器宕机也不会影响到。

MySQL 事务

事务就是一组原子性的sql,是一个独立的工作单元。

我们可以通过设置 AUTOCOMMIT 变量来启动或则禁用自动提交模式。 设置1表示启用AUTOCOMMIT,0表示禁用AUTOCOMMIT。

MySQL中默认的是采取自动提交模式(AutoCommit),

  • 只要不是显示的开启一个事务,每个查询操作都被当做一个事务执行提交的操作。
  • 显示的开启一个事务开启,当用户执行commit命令时当前事务提交。从用户执行start transaction命令到用户执行commit命令之间的一系列操作为一个完整的事务周期。若不执行commit命令,系统则默认事务回滚。

事务并发带来的数据问题

隔离级别(isolation level),是指事务与事务之间的隔离程度,事务之间的隔离级别不同,会引发下面不同的问题

  • Read Uncommitted(未提交读、脏读):在该隔离级别,所有事务可以看到其他未提交事务的执行结果。读取未提交的数据,也被称之为脏读(Dirty Read)。
  • Read Committed(提交读、不可重复读):一个事务只能看见已经提交事务所做的改变。这种隔离级别也支持不可重复读,同一事务的其他实例在该实例处理其间可能会有新的 commit,所以同一 select 查询可能返回不同结果
  • Repeatable Read(可重复读、幻读)MySQL的默认事务隔离级别(MVVC的简单介绍,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行,但插入的时候却却提示已经存在了,这就是幻读不可重复读描述的侧重点是修改操作,而幻读描述的侧重点是添加和删除操作
  • Serializable(可串行化)这是最高的隔离级别,它强制事务都是串行执行的,使之不可能相互冲突,从而解决幻读问题。换言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

MVVC 实现原理介绍

MVCC(multiple-version-concurrency-control)是个行级锁的变种,它在普通读情况下避免了加锁操作,对于写操作只锁定必要的行

InnoDB 实现MVCC,是通过ReadView + Undo Log实现的,Undo Log 保存了历史快照,ReadView可见性规则帮助判断当前版本的数据是否可见。

快照读: 读取的是记录数据的可见版本(有旧的版本)。不加锁,普通的select语句都是快照读,如:

代码语言:javascript
复制
select * from user where id = 1;

当前读:读取的是记录数据的最新版本,显式加锁的都是当前读

代码语言:javascript
复制
select * from user where id = 1 for update;
select * from user where id = 1 lock in share mode;

MVVC 的一些概念

  • 事务版本号:事务每次开启时,都会从数据库获得一个自增长的事务ID
  • 隐藏字段:每行记录都有两个隐藏列
    • trx_id :记录对应的事务 id
    • roll_pointer数据的版本链,通过这个可以找到旧的数据
  • undo log:回滚日志,存储的是老版本数据。在表记录修改之前,会先把原始数据拷贝到 undo log 里,如果事务回滚,即可以通过 undo log 来还原数据。或者如果当前记录行不可见,可以顺着undo log链找到满足其可见性条件的记录行版本
  • ReadView:保存了当前事务开启时所有活跃的事务列表,ReadView 保存了不应该让这个事务看到的其他事务 ID 列表,查询时需要根据这个进行条件判断

如何查询一条记录

  1. 获取事务自己事务ID,即trx_id。(这个也不是select的时候获取的,而是这个事务开启的时候获取的 也就是begin的时候)
  2. 获取ReadView(这个才是select的时候才会生成的)
  3. 数据库表中如果查询到数据,那就到ReadView中的事务版本号进行比较。
  4. 如果不符合ReadView的可见性规则, 即就需要Undo log中历史快照,直到返回符合规则的数据;

参考博客

MVVC原理详解

深入理解 MySQL 锁-事务-并发

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数据库存储引擎
  • 数据库ACID
  • MySQL 事务
  • MVVC 实现原理介绍
    • 如何查询一条记录
    • 参考博客
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档