1、事务

1.2、目的

事务将数据库从一种一致性状态转换为另一种一致性状态;

1.3、组成

事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成;
其中单条语句会默认自动添加事务控制语句,而多条SQL语句需要手动添加事务控制语句。

1.4、特征

在数据库提交事务时,可以确保要么所有修改都已经保存,要么所有修改都不保存;
事务是访问并更新数据库各种数据项的一个程序执行单元。
在 MySQL innodb 下,每一条语句都是事务;可以通过 set autocommit = 0; 设置当前会话手动提交;

1.5、事务控制语句

-- 显示开启事务
START TRANSACTION | BEGIN
-- 提交事务,并使得已对数据库做的所有修改持久化
COMMIT
-- 回滚事务,结束用户的事务,并撤销正在进行的所有未提交的修改
ROLLBACK
-- 创建一个保存点,一个事务可以有多个保存点
SAVEPOINT identifier
-- 删除一个保存点
RELEASE SAVEPOINT identifier
-- 事务回滚到保存点
ROLLBACK TO [SAVEPOINT] identifier

2、ACID特性分析

2.1、原子性(A)

  事务操作要么都做(提交),要么都不做(回滚);事务是访问并更新数据库各种数据项的一个程序执行单元,是不可分割的工作单位;
  通过 undolog 来实现回滚操作。undolog 记录的是事务每步具体操作,当回滚时,回放事务具体操作的逆运算;undolog存储在共享表中;

2.2、隔离性(I)

  事务的隔离性要求每个读写事务的对象对其他事务的操作对象能相互分离,并发事务之间不会相互影响,设定了不同程度的隔离级别,通过适度破环一致性,得以提高性能;通过 MVCC 和 锁来实现;MVCC 时多版本并发控制,主要解决一致性非锁定读,通过记录和获取行版本,而不是使用锁来限制读操作,从而实现高效并发读性能。锁用来处理并发 DML 操作;数据库中提供粒度锁的策略,针对表(聚集索引B+树)、页(聚集索引B+树叶子节点)、行(叶子节点当中某一段记录行)三种粒度加锁;

2.3、持久性(D)

  事务提交后,事务DML操作将会持久化(写入 redolog 磁盘文件 哪一个页 页偏移值 具体数据);即使发生宕机等故障,数据库也能将数据恢复。redolog 记录的是物理日志;

2.4、一致性(C)

  一致性指事务将数据库从一种一致性状态转变为下一种一致性的状态,在事务执行前后,数据库完整性约束没有被破坏;一个事务单元需要提交之后才会被其他事务可见。例如:一个表的姓名是唯一键,如果一个事务对姓名进行修改,但是在事务提交或事务回滚后,表中的姓名变得不唯一了,这样就破坏了一致性;一致性由原子性、隔离性以及持久性共同来维护的。

2.5、隔离级别

ISO 和 ANIS SQL 标准制定了四种事务隔离级别的标准,各数据库厂商在正确性和性能之间做了妥协,并没有严格遵循这些标准;MySQL innodb默认支持的隔离级别是REPEATABLE READ;

2.5.1 READ UNCOMMITTED

读未提交;该级别下读不加锁,写加排他锁,写锁在事务提交或回滚后释放锁;

读:不做任何处理;
写:自动加X锁

2.5.2、READ COMMITTED

读已提交(RC);从该级别后支持 MVCC (多版本并发控制),也就是提供一致性非锁定读;此时读取操作读取历史快照数据;该隔离级别下读取历史版本的最新数据,所以读取的是已提交的数据;

读:mvcc,读取最新版本的行数据(关于mvcc可以参考 4、mvcc)
写:自动加X锁

2.5.3、REPEATABLE READ

可重复读(RR);该级别下也支持 MVCC,此时读取操作读取事务开始时的版本数据;
MYSQL 默认的隔离级别
读:mvcc,读取事务开始前版本的行数据,若是其他事务有插入和删除行数据并提交,在当前事务下也能知道。
写:自动加X锁

2.5.4、SERIALIZABLE

可串行化;该级别下给读加了共享锁;所以事务都是串行化的执行;此时隔离级别最严苛;

读:自动加S锁(next-key lock)
写:自动加X锁

2.6 命令

-- 设置隔离级别
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 或者采用下面的方式设置隔离级别
SET @@tx_isolation = 'REPEATABLE READ';
SET @@global.tx_isolation = 'REPEATABLE READ';
-- 查看全局隔离级别
SELECT @@global.tx_isolation;
-- 查看当前会话隔离级别
SELECT @@session.tx_isolation;
SELECT @@tx_isolation; -- 手动给读加 S 锁
SELECT ... LOCK IN SHARE MODE;
-- 手动给读加 X 锁
SELECT ... FOR UPDATE;
-- 查看当前锁信息 SELECT * FROM information_schema.innodb_locks;

3、锁

锁机制用于管理对共享资源的并发访问;用来实现事务的隔离级别 ;

3.1、锁类型

共享锁和排他锁都是行级锁;MySQL当中事务采用的是粒度锁;针对表(B+树)、页(B+树叶子节点)、行(B+树叶子节点当中某一段记录行)三种粒度加锁,简称为表锁、页锁和行锁;

意向共享锁和意向排他锁都是表级别的锁;

3.2、共享锁

事务读操作加的锁;对某一行加锁;
在 SERIALIZABLE 隔离级别下,默认帮读操作加共享锁;
在 REPEATABLE READ 隔离级别下,需手动加共享锁,可解决幻读问题;
在 READ COMMITTED 隔离级别下,没必要加共享锁,采用的是 MVCC; 在 READ UNCOMMITTED 隔离级别下,既没有加锁也没有使用 MVCC;

3.3、排他锁(X)

事务删除或更新加的锁;对某一行加锁;
在4种隔离级别下,都添加了排他锁,事务提交或事务回滚后释放锁;

3.4、意向共享锁(IS)

对一张表中某几行加的共享锁;、

3.5、意向排他锁(IX)

对一张表中某几行加的排他锁;
目的(IX/IS):为了告诉其他事务,此时这条表被一个事务在访问;
作用(IX/IS):排除表级别读写锁 (全面扫描加锁);、

3.6、锁的兼容性


冲突即只能有一个锁对应的事务运作,兼容则是多个所对应的事物都可以同时进行;
注意:意向锁只有可能和表锁出现冲突,上表中的意向锁与s/x锁的冲突是指表锁!!!!

由于innodb支持的是行级别的锁,意向锁并不会阻塞除了全表扫描以外的任何请求;
意向锁之间是互相兼容的;
IS 只对排他锁(表锁)不兼容;
当想为某一行添加 S 锁,先自动为所在的页和表添加意向锁 IS,再为该行添加 S 锁;
当想为某一行添加 X 锁,先自动为所在的页和表添加意向锁 IX,再为该行添加 X 锁;
当事务试图读或写某一条记录时,会先在表上加上意向锁,然后才在要操作的记录上加上读锁或写锁。这样判断表中是否有记录加锁就很简单了,只要看下表上是否有意向锁就行了。意向锁之间是不会产生冲突的,也不和 AUTO_INC 表锁冲突,它只会阻塞表级读锁或表级写锁,另外,意向锁也不会和行锁冲突,行锁只会和行锁冲突。

3.7、锁算法

3.7.1、Record Lock

记录锁,单个行记录上的锁;

3.7.2、Gap Lock(重点)

间隙锁,锁定一个范围,但不包含记录本身;全开区间;
REPEATABLE READ级别及以上支持间隙锁;
如果 REPEATABLE READ 修改 innodb_locks_unsafe_for_binlog = 0 ,那么隔离级别相当于
退化为 READ COMMITTED;

-- 查看是否支持间隙锁,默认支持,也就是 innodb_locks_unsafe_for_binlog = 0;
SELECT @@innodb_locks_unsafe_for_binlog;

3.7.3、Next-Key Lock

记录锁+间隙锁,锁定一个范围,并且锁住记录本身;左开右闭区间;
REPEATABLE READ级别及以上支持Next-Key Lock;

3.7.4、Insert Intention Lock

插入意向锁,insert操作的时候产生;在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。
假设有一个记录索引包含键值4和7,两个不同的事务分别插入5和6,每个事务都会产生一个加在4-7之间的插入意向锁,获取在插入行上的排它锁,但是不会被互相锁住,因为数据行并不冲突。

3.7.5锁兼容


横向:表示已经持有的锁;纵向:表示正在请求的锁;
一个事务已经获取了插入意向锁,对其他事务是没有任何影响的;
一个事务想要获取插入意向锁,如果有其他事务已经加了 gap lock 或 Next-key lock 则会阻塞;这个是重点,死锁之源!!!

3.7.6、AUTO-INC Lock(AI锁)

自增锁,是一种特殊的表级锁,发生在 AUTO_INCREMENT 约束下的插入操作;采用的一种特殊的表锁机制(较低概率造成B+树分裂);完成对自增长值插入的SQL语句后立即释放;在大数据量的插入会影响插入性能,因为另一个事务中的插入会被阻塞;从MySQL 5.1.22开始提供一种轻量级互斥量的自增长实现机制,该机制提高了自增长值插入的性能;

3.8锁的对象

行级锁是针对表的索引加锁;索引包括聚集索引和辅助索引;
表级锁是针对页或表进行加锁;
重点考虑 InnoDB 在 read committed 和 repeatable read 级别下锁的情况;
如下图 students 表作为实例,其中 id 为主键,no(学号)为辅助唯一索引,name(姓名)和
age(年龄)为二级非唯一索引,score(学分)无索引。

分别讨论:
1、聚集索引,查询命中: UPDATE students SET score = 100 WHERE id = 15;

2、聚集索引,查询未命中: UPDATE students SET score = 100 WHERE id = 16;
RC没加锁,RR加了(15,18)的gap锁
3、辅助唯一索引,查询命中: UPDATE students SET score = 100 WHERE no = ‘S0003’;
4、辅助唯一索引,查询未命中: UPDATE students SET score = 100 WHERE no = ‘S0008’;

RC没加锁,RR加了(s0007,+无穷)的gap锁
5、辅助非唯一索引,查询命中: UPDATE students SET score = 100 WHERE name = ‘Tom’;

RR加了(Rose,Tom)、(Tom,Tom)、(Tom,+无穷)三个gap锁
6、辅助非唯一索引,查询未命中: UPDATE students SET score = 100 WHERE name = ‘John’;

John按照排序是在Jim与Rose之间,所以RR里面加了(Jim,Rose)的gap锁
7、无索引: UPDATE students SET score = 100 WHERE score = 22;

8、聚集索引,范围查询: UPDATE students SET score = 100 WHERE id <= 20;
RR中的30是特殊情况,不讨论,有时候会加(20,30]

9、辅助索引,范围查询: UPDATE students SET score = 100 WHERE age <= 23;

10、修改索引值: UPDATE students SET name = ‘John’ WHERE id = 15;

4、mvcc

  多版本并发控制;用来实现一致性的非锁定读;非锁定读是指不需要等待访问的行上X锁的释放;
  在 read committed 和 repeatable read下,innodb使用MVCC;然后对于快照数据的定义不同;在 read committed 隔离级别下,对于快照数据总是读取被锁定行的最新一份快照数据;而在repeatable read 隔离级别下,对于快照数据总是读取事务开始时的行数据版本;

思考:为什么读取快照数据不需要上锁?
  因为没有事务需要对历史的数据进行修改操作;

最后

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

数据库之mysql事务原理分析与锁机制 详解相关推荐

  1. MySQL事务原理分析(ACID特性、隔离级别、锁、MVCC、并发读异常、并发死锁以及如何避免死锁)

    MySQL事务原理分析(ACID特性.隔离级别.锁.MVCC.并发读异常.并发死锁以及如何避免死锁) 一.事务 目的 组成 特征 事务空间语句 二.ACID特性 原子性(A) 隔离性(I) 持久性(d ...

  2. Linux服务器开发【有用知识】—MySQL事务原理分析

    前言 今天的目标是学习MySQL事务原理分析,但是却似乎总是非常不顺利,概念和实操实在多到令人发指,故干脆轻松学完一节课,等到时机到了再重新刷一遍吧! 一.事务是什么? 将数据库从一致性状态转化成另一 ...

  3. MySQL锁、事务隔离级别、MVCC机制详解、间隙锁、死锁等

    一. 简介 1. 锁定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供需要用户共享的资源.如何保证数据并 ...

  4. mysql innodb 的锁机制_Mysql之Innodb锁机制详解

    InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.关于事务我们之前有专题介绍,这里就着重介绍下它的锁机制. 总的来说,InnoDB按照不同的分类共有 ...

  5. 【 卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10)】

    卷积神经网络CNN 数学原理分析与源码详解 深度学习 Pytorch笔记 B站刘二大人(9/10) 本章主要进行卷积神经网络的相关数学原理和pytorch的对应模块进行推导分析 代码也是通过demo实 ...

  6. MYSQL事务原理分析

    目录 事务是什么 ACID特性 原子性(A) 隔离性(I) 持久性(D) 一致性(C) 隔离级别 简介 有些什么 READ UNCOMMITTED(读未提交) READ COMMITTED(读已提交) ...

  7. mysql表锁机制详解

    为了给高并发情况下的mysql进行更好的优化,有必要了解一下mysql查询更新时的锁表机制. 一.概述 MySQL有三种锁的级别:页级.表级.行级. MyISAM和MEMORY存储引擎采用的是表级锁( ...

  8. Mysql高级部分--索引、锁等详解

    1.索引 1.1.概念 1.2.索引的优势和劣势 1.3.索引的分类 1.4.mysql索引结构 1.4.1.B树的检索原理 1.初始化介绍: 一颗B+树,浅蓝色的块我们称之为一个磁盘块,可以看到每个 ...

  9. MySQL锁机制详解-表锁与行锁

    文章目录 1. 数据库锁理论 2. 锁的分类 2.1 按数据操作的类型分类 2.2 按数据操作的颗粒度分类 3. 表锁的应用 3.1 表锁相关命令 3.2 给表加表共享读锁 3.3 给表加表独占写锁 ...

最新文章

  1. C++longest common subsequence最长公共子序列的实现(附完整源码)
  2. 计算机在盲童音乐教学中的具体应用,计算机在高校中的具体应用
  3. zabbix华为交换机模板_【教程】思科交换机镜像端口配置实例
  4. 娄底八中的初中计算机考试,众人同心勤耕耘 敢叫日月换新天
  5. Logback配置文件这么写,TPS提高10倍!
  6. Linux 命令(15)—— umask 命令(builtin)
  7. 24. 使用GitHub
  8. 基于javaweb+mysql数据库实现的宠物领养|流浪猫狗网站项目源代码
  9. 极智开发 | Go 安装教程
  10. 高阶技术管理岗空降落地实践指南
  11. 铲雪车(snow)[欧拉回路]
  12. 化合物相似性搜索_SCIFINDER相似结构搜索教程
  13. locality sensitive hashing(LSH)原理和具体实现
  14. 重读经典(CLIP下):《Learning Transferable Visual Models From Natural Language Supervision》
  15. System.gc()的理解
  16. 小花经过春雨的一番滋润
  17. C语言中fscanf函数
  18. 【UI】产品设计之什么是色彩情绪
  19. android 字母索引 listview
  20. 品管七大手法-3散布图(转载)

热门文章

  1. C#通过Windows API捕获窗,获取窗口文本(FindWindow、GetWindowText),附录:Windows窗口消息大全、Windows API大全
  2. Ultimaker2 3D打印机源文件在线公布
  3. 算法导论例题——钢管切割
  4. 词嵌入 word embedding
  5. erp服务器性能测试,金蝶ERP性能测试经验分享
  6. uboot代码解析1:根据目的找主线
  7. MATLAB读RGB888数据显示图片
  8. 第七次网页前端培训笔记
  9. C语言递归函数——汉诺塔问题笔记
  10. 靶场攻略 | Moriarty Corp渗透测试