事务

  事务的组成可由一条非常简单的SQL语句组成,也可由一组复杂的SQL语句组成。

特征

  事务具有以下特征:  

  (1)在数据提交时,可以确保要么所有修改都已保存,要么所有修改不保存;

  (2)事务是访问并更新数据库各种数据项的一个执行单元;

  (3)在innodb下,每一条语句都是事务,可以通过set autocommit = 0 (默认值1,不需要手动添加开始事务和提交语句),设置当前会话手动提交,一般需要执行多条语句的时候,就会显式地开始事务。

指令

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

事务的ACID特性

  (1)原子性

    a. 事务要么都做(提交),要么都不做(回滚);

    b.事务是访问并更新数据库各种数据的执行单元,执行单元是不可分割的单位;

    c.通过undolog来实现回滚(语句的操作都会记录在undolog中),当回滚时,回放事务具体操作的逆运算

  (2)隔离性

    a.mysql在处理每一个连接的请求是并发的,所以需要隔离性;

    b.事务的隔离性要求每个读写事务对象对其他事务的操作对象能互相分离,也就是事务提交前对其他事务不可见

    c.通过MVCC和锁来实现,MVCC是多版本并发控制,主要解决一致性非锁定读,通过记录和获取行版本,而不是通过锁来限制读操作,从而实现高并发读性能;

    d.通过锁来处理数据库的DML操作,数据库提供了针对表(聚集索引B+树)、页(聚集索引B+树的叶子节点)、行(叶子节点当中某一段记录行)等三种粒度加锁

  (3)持久性

    a.事务提交后,事务DML操作将会持久化(写入redolog磁盘文件,那一页,页偏移值,具体数据);

    b.即使发生宕机等故障,数据库也能将数据恢复,redolog记录着物理日志。

  (4)一致性

    一致性指事务将数据库从一种一致性状态转变为下一种一致性的状态,在事务执行前后,数据库完整性约束没有被破坏。

  MYSQL的DML操作整个流程,首先修改内存的数据,同时写到redolog(这里只有一次磁盘IO),另外有一个master线程,异步地将内存中的脏数据(内存与磁盘不一致的数据)写到聚集索引B+树中(.idb文件)。

事务并发异常

  (1)脏读

    事务A可以读到另一个事务B中未提交的数据,也就是事务A读取到脏数据

    现象:读到未提交数据

    原因:read uncommitted读未加锁,也没有MVCC

    解决:添加MVCC持支

  (2)不可重复读

    事务A可以读到事务B中提交的数据,通常发生在一个事务中两次读到的数据是不一样的情况;

    现象:读到其他事务提交的数据,造成两次读结果不一致;

    原因:read committed隔离级别下MVCC,读取最新的历史版本数据;

    解决:修改MVCC读取定义,读取事务开始前的历史版本数据;

  (3)幻读

    事务中一次读操作不能支撑接下来的业务逻辑,通常发生在一个事务中,一次读判断接着写操作失败的情况;

    现象:一个事务中某次读操作不能作为接下来业务逻辑的数据;

    原因:repeatable read 隔离级别下,读操作使用MVCC,读操作未加锁,从而能进行写操作;

    解决:手动给读操作加S锁或者X锁,通过next-key lock(间隙锁)锁住读取范围,避免范围内加入数据

C/C++Linux服务器开发高级架构师/C++后台开发架构师​免费学习地址

另外还整理一些C++后台开发架构师 相关学习资料,面试题,教学视频,以及学习路线图,免费分享有需要的可以自行添加:Q群:720209036 点击加入~ 群文件共享

隔离级别 

  (1)READ UNCOMMITTED

    读:读未提交,不做任何处理

    写:自动加X锁

  (2)READ COMMITTED

    读:MVCC,读已提交,读最新版本的数据

    写:自动加X锁

  (3)REPEATABLE READ

    读:MVCC,可重复读,读事务开始前版本的行数据

    写:自动加X锁

  (4)SERIALIZABLE

    可串行化,该级别下给读加了共享锁,所以事务都是串行化的执行,此时隔离级别最苛刻,使用场景在分布式数据库;

    读:自动加S锁(next-key lock 间隙锁)

    写:自动加X锁

  以上隔离级别中,写操作都会自动加X锁,对于读操作,除SERIALIZABLE会自动加S锁外,其他的隔离级别不做任何处理;所以根据不同的业务来使用隔离级别,在正确性与性能间做个抉择。

MVCC

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

  思考:为什么读取快照数据不需要上锁?

    因为没有事务需要对历史的数据进行修改操作。

  锁的机制用于管理共享资源的并发访问,用来实现事务的隔离级别,也就是说事务的隔离性是通过锁实现的,在事务中锁都是在提交或者回滚后才释放。

  (1)共享锁(S)

    相当于读锁,是个行锁,事务读操作加锁,对某一行加锁

    a.在 READ UNCOMMITTED 隔离级别下,既没有加锁也没有使用 MVCC;     b.在 READ COMMITTED 隔离级别下,没必要加共享锁,采用的是 MVCC,加锁也不能解决幻读问题;     c.在 REPEATABLE READ 隔离级别下,需手动加共享锁,可解决幻读问题,因为加的实际是一个间隙锁,把某个范围锁住了;     d.在 SERIALIZABLE 隔离级别下,默认帮读操作加共享锁。

  (2)排他锁(X)

    相当于写锁,是个行锁,事务删除或更新加的锁,对某一行加锁;在四种隔离级别下,都添加排他锁,事务提交或者回滚后释放。

  (3)意向(IS)共享锁

    对一张表某几行加的共享锁。

  (4)意向(IX)排他锁

    对一张表某几行加的排他锁。

  当想为某一行添加S锁,先自动为所在的页和表添加意向共享锁(IS),再为该行添加S锁;

  当想为某一行添加X锁,先自动为所在的页和表添加意向排他锁(IX),再为该行添加X锁;

  表级锁用户是不能更改的,因为用户在为某一行添加共享锁、排他锁时,自动在页和表上添加相关的意向共享锁,或意向排他锁,再为修改行添加共享锁或排他锁,所以表级锁、意向锁不是由程序员控制的,而是自动添加的。

  行级锁是针对表的索引加锁,这里的索引包括聚集索引和辅助索引,表级锁是针对页或表进行加锁。

锁的算法

  (1)Record Lock

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

  (2)Gap Lock

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

  (3)Next-Key-Lock

    记录锁+间隙锁,锁定一个范围,并且锁住记录本身,左开右闭

  (4)Inster Intention Lock

    插入意向锁,inster操作的时候产生,在多事务同时写入不同数据至同一索引间隙的时候,并不需要等待其他事务完成,不会发生锁等待。

    例如:假设有一个记录索引包含键值4和7,两个不同的事务分别插入5和6,每个事务都会产生一个加在4-7之间的插入意向锁,获取在插入行上的排他锁,但是不会被互相锁住,因为数据行并不冲突。

  (5)AUTO_INC Lock

    自增锁,是一种特殊的表级锁,发生在AUTO_INCREMENT约束下的插入操作;采用一种特殊的表锁机制,完成对自增长值插入的SQL语句后立即释放;在有大量数据插入时,会影响插入性能,因为另外一个事务中的插入会被阻塞(锁);从MYSQL5.12开始,提供了一种轻量级互斥量的自增长实现机制,该机制提高了自增从值得插入的性能。

redolog(重做日志)

  redo日志用来实现事务的持久性,内存中包含redo log buffer,磁盘中包含redo log file;当事务提交时,必须将该事务的所有日志写入到重做日志文件进行持久化,待事务的commit操作完成才完成事务提交;redo log顺序写,记录的是对每个页的修改(页、页偏移量、以及修改的内容);在数据库运行时不需要对redo log的文件进行读取操作,只有发生宕机的时候,才会拿redo log进行恢复。

undolog(回滚日志)

  undo日志用来帮助事务回滚以及MVCC的功能,存储在共享表空间中;undo log是逻辑日志,回滚时将数据库逻辑地恢复到原来的样子,根据undo log的记录,做之前的逆运算;比如事务中有inster操作,那么执行delete操作,对于update操作执行相反的update操作;同时undo log日志记录行的版本信息,用于处理MVCC功能。

  以上的两种日志应区别于binlog(二进制日志),binlog用于复制,在主从复制中,从库利用主库上的binlog进行重播。

原文地址:MySQL之事务 - MrJuJu - 博客园

详解MySQL之事务相关推荐

  1. mysql 事物的持久性是指_详解MySQL中事务的持久性实现原理

    前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什 ...

  2. mysql执行事务的语句_详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  3. 详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  4. 详解mysql事务_详解MySQL执行事务的语法和流程

    摘要:MySQL 提供了多种存储引擎来支持事务. MySQL 提供了多种存储引擎来支持事务.支持事务的存储引擎有 InnoDB 和 BDB,其中,InnoDB 存储引擎事务主要通过 UNDO 日志和 ...

  5. 详解Mysql分布式事务XA

    在开发中,为了降低单点压力,通常会根据业务情况进行分表分库,将表分布在不同的库中(库可能分布在不同的机器上).在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败 ...

  6. 一文详解Mysql锁事务隔离级别

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

  7. mysql如何查看事务日记_详解 Mysql 事务和Mysql 日志

    事务特性 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破 ...

  8. mysql 事务 for update,mysql事务锁_详解mysql 锁表 for update

    摘要 腾兴网为您分享:详解mysql 锁表 for update,智慧农业,真还赚,悦读小说,学习帮等软件知识,以及电池管家,三国群英传3,userland,运满满货主版,王者荣耀,简单3d动画,嘉丽 ...

  9. mysqldump全量恢复_删库不跑路-详解MySQL数据恢复

    日常工作中,总会有因手抖.写错条件.写错表名.错连生产库造成的误删库表和数据的事情发生,那么,如果连数据都恢复不了,还要什么 DBA. 相关文章 MySQL备份策略:https://segmentfa ...

最新文章

  1. FTP主动模式与被动模式的解决与原理
  2. vim 撤销上一步操作_Linux笔记(4):vim入门
  3. ajax 获取服务器返回的XML字符串
  4. 这个网站绝了,收录近600条Linux系统命令
  5. 小心DataAdapter陷阱
  6. 试卷批分pascal程序
  7. failed to find romfile efi-virtio.rom
  8. 各银行汇款手续费之比较
  9. 解决方案售前的知识管理解决方案
  10. Maven的基本使用
  11. Springboot+网上投资借贷中介服务 毕业设计-附源码221506
  12. 转特权:NIOS2下的SDHC调试
  13. ASR系统第二讲 语音识别基础
  14. 区块链学习之Web3j入门(一)
  15. 15组。政务一体化平台
  16. stty的使用 和 RTSCTS问题
  17. 网络系统管理赛项之Debian 九. 2021年网络系统管理项目-模块A--样题(一)
  18. 【python3】python实现多线程(简单操作)
  19. [日推荐]『爱比趣』有意思的体育社区
  20. 分享一个有意思的科普网站

热门文章

  1. 浅谈主机间网络通信实际过程
  2. Mariadb互为主从(双主模式)配置
  3. 一些Java实用技巧(量变转变为质变后会单独整理出来)
  4. 深度学习地震勘探入门
  5. 安霸CV1 SOC芯片
  6. 人活着总是要有点精神的
  7. [猎豹网校 Lua] 第二课.HelloLua
  8. GiB 与 GB 的区别
  9. code-push常用命令
  10. -- 38、查询课程编号为01且课程成绩在80分以上的学生的学号和姓名