一、mysql事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎可以成功执行该组全部语句,那么就执行该组语句。如果其中有任何一条语句不能执行,那么所有的语句都不会执行。也就是说,事务内的语句要么全部执行成功,要么全部执行失败。

1、事务的ACID特性

事务需要系统严格的支持ACID特性,ACID表示原子性、一致性、隔离性和持久性。一个运行良好的事务处理系统,必须具备这些标准特征。

原子性:一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中一部分操作,这就是事务的原子性。

一致性:数据库总是从一个一致性的状态换到另外一个一致性的状态。一致性确保了,即使系统已经执行了事务中的部分操作后系统崩溃,数据也不会有损失,因为事务最终没有提交,所以事务中所做的修改液不会保存到数据库中。

隔离性:通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。如果事务的操作正在执行的过程中,又有其他事务需要操作该数据,那么其他事务看到的还是原始数据。

持久性:一旦事务提交,则其所做的修改就会永远保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

2、隔离级别

隔离性其实比想象的要复杂。在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,那些在事务内核事物间是可见的,那些是不可见的。较低级别的隔离通常可以执行更高的并发,系统的开销也更低。

READ UNCOMMITTED(未提交读):在该级别事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也称为赃读。这个级别会导致很多问题,从性能上来说,该级别不会比其他级别好太多,但缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少。

READ COMMITTED(提交读):大多数数据库系统的默认隔离级别都是READ COMMITED(mysql不是)。该级别满足前面提到的隔离性的简单定义:一个事务开始时,只能看见已经提交的书屋所做的修改。换句话说,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候也就做不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。

REPEATABLE READ(可重复读):该级别解决了赃读的问题。该级别保证了在同一个事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题。所谓幻读-----指的是当某个事务在读取某个范围内的记录时,另外一个事务又在范围内插入了新的记录,当之前的事务再次读取该范围内记录时,会产生幻行。Innodb存储引擎通过多版本并发控制(MVCC)解决了幻读的问题。

SERIALIZABLE(可串行读):这是最高的隔离级别。他通过强制事务串行执行,避免了前面说的幻读的问题。简单来说,该级别会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用的问题。实际应用中也很少用到这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

3、死锁问题

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务视图以不同的顺序锁定资源时,就可能会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。

为了解决这种问题,数据库系统实现了各种死锁检测和死锁超时机制。越复杂的系统,越能检测到死锁的循环依赖,并立即返回一个错误。这种解决方式是很有效,否则死锁会导致出现非常慢的查询。还有一种解决方式,就是当查询的时间达到锁等待超时的设定后放弃锁请求,这种方式通常来说不太好。InnoDB目前处理死锁的方法是,将持有最少行级排他的事务进行回滚。

锁的行为和顺序是和存储引擎相关的。以同样的顺序执行语句,有些存储引擎会产生死锁,有些则不会。死锁的产生有双重原因:有些是因为真正的数据冲突,这种情况通常很难避免,但有些则完全是由于存储引擎的实现方式导致的。

死锁发生以后,只有部分或者完全回滚其中一个事务,才能打破死锁。对于事务型的系统,这是无法避免的,所以应用程序在设计时必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。

4、事务日志

事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把修改修改行为记录到持久在磁盘上的事务日志中,而不是每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一块区域内的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式相对来说要快的多。事务日志持久以后,内存中被修改的数据在后台可以慢慢的刷回到磁盘。目前大多数存储引擎都是这样实现的,我们通常称之为预写式日志,修改数据需要写两次磁盘。

如果数据的修改已经记录到事务日志并持久化,但数据本身还没有写回到磁盘,此时系统崩溃,存储引擎在重启时能够自动恢复这部分修改的数据。

二、多版本并发控制

mysql的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,他们一般都同时实现了多版本并发控制(MVCC)。可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事物看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。InnoDB的MVCC,是通过在每行记录后面保存隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。在REPEATABLE READ隔离级别下,MVCC工作如下:

SELECT----InnoDB会根据以下两个条件检查每行记录:①InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始之前已经存在的,要么是事务自身插入或者修改过的;②行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

INSERT----InnoDB为新插入的每一行保存当前系统版本号作为行版本号。

DELETE----InnoDB为删除的每一行保存当前系统版本号作为删除标示。

UPDATE----InnoDB会插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标示。

保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

MVCC只在REPEATABLE READ和READ COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁。

mysql事务并发控制_mysql事务和多版本并发控制详解相关推荐

  1. mysql linux文件_MySQL在Linux系统下配置文件详解

    在日常的的开发过程中接触到了SQLServer和MySQL数据库的操作性问题,可能是以前接触的都是SQL Server,才开始接触MySQL,总感觉使用MySQL没有使用SQLserver那么顺手,一 ...

  2. mysql master 配置_MySQL双Master配置的方法详解

    刚刚抽空做了一下MYSQL 的主主同步.把步骤写下来,至于会出现的什么问题,以后随时更新.这里我同步的数据库是TEST1.环境描述.主机:192.168.0.231(A)主机:192.168.0.23 ...

  3. 给mysql 授权 命令_mysql中授权命令grant用法详解:

    mysql中授权命令grant用法详解: mysql中可以给你一个用户授予如select,insert,update,delete等其中的一个或者多个权限,主要使用grant命令,用法格式为: gra ...

  4. mysql escape关键字_MySQL中ESCAPE关键字的用法详解

    MySQL转义 转义即表示转义字符原来的语义,一个转义字符的目的是开始一个字符序列,使得转义字符开头的该字符序列具有不同于该字符序列单独出现时的语义. MySQL中,转义字符以"\" ...

  5. mysql 事件统计_mysql事件统计之PERFORMANCE_SCHEMA基础详解

    概述 MySQL 5.5开始新增一个数据库:PERFORMANCE_SCHEMA,主要用于收集数据库服务器性能参数.并且库里表的存储引擎均为PERFORMANCE_SCHEMA,而用户是不能创建存储引 ...

  6. mysql binlog 回退_MYSQL Binglog分析利器:binlog2sql使用详解

    大部分使用mysql的业务也都会开启binlog,用以记录数据库的更新操作.当然binlog的格式大家也都比较清楚,分别是statement.mixed.row模式.针对row格式的binlog,它以 ...

  7. jdbc mysql 换行符_mysql JDBC URL格式各个参数详解

    mysql JDBC URL格式如下: jdbc:mysql://[host:port],[host:port].../[database][?参数名1][=参数值1][&参数名2][=参数值 ...

  8. 免安装mysql配置图解_mysql免安装版配置步骤详解分享

    1.准备工作 下载mysql的最新免安装版本mysql-noinstall-5.1.53-win32.zip,解压缩到相关目录,如:d:\\ mysql-noinstall-5.1.53-win32. ...

  9. mysql密码高级_MySQL数据库高级操作(图文详解)

    数据表高级操作 准备工作:安装MySQL数据库 create database CLASS; use CLASS; create table TEST (id int not null,name ch ...

  10. mysql week 参数_MySQL week()函数及参数mode详解

    通常,一年的正常年份为365天,闰年为366天.一年又可以分为许多周,每周有7天. 所以一年,我们经常有365/7 = 52周,周范围是从1到52. 要查看给定日期属于哪个周数,您可以使用WEEK函数 ...

最新文章

  1. C++用substr()函数消除前后空格
  2. (转)Spring读书笔记-----Spring的Bean之Bean的基本概念
  3. ios8 UITableView section不显示
  4. android 浏览器 div穿透,解决IE 上重叠div 对 mouseover 事件的穿透方法之一
  5. PDA手持终端WinCE系统连接SqlServer数据库
  6. 算法题2 插序算法
  7. TCMalloc : Thread-Caching Malloc
  8. ava集合---ArrayList的实现原理
  9. Webservice调用方式:axis,soap详解
  10. 白话说大数据算法C4.5
  11. 在ubuntu 的QT中不能使用搜狗输入法
  12. win10任务栏卡死重启也没用
  13. 计算机网络-第一章(b站王道考研)
  14. 双向迭代器实现对该商品名称数组的双向(向前和向后)遍历。
  15. Google Maps基站定位
  16. 用户冷启动问题现存解决办法汇总
  17. 31.进程管理之进程概览,及ps命令详解,ps -ef,ps aux,ps -le,ps -l输出详解和示例
  18. java 过期数据_TTL过期的数据包丢失
  19. 过期策略(TTL)与淘汰策略
  20. mysql中字段约束unique_什么是MySQL UNIQUE约束,我们如何将其应用于表的字段?

热门文章

  1. Magnetism and Earnshaw‘s Theorem
  2. 2020年春季学期信号与系统课程作业参考答案-第十二次作业
  3. 关于计算机组装的作文,电脑小白组装电脑,能写出这样的配置,在下佩服!
  4. html5盒子模型作业,html5 盒子模型案例
  5. php二维数组按照自定义方式对键值排序,PHP 对一个给定的二维数组按照指定的键值进行排序...
  6. 如何去除table的边框_如何擦玻璃,这些擦玻璃知识很实用
  7. mysql union 后 sum_mysql:多表查询
  8. java web 初始化方法_Java Web(二) 类的初始化及初始化顺序
  9. 数据包skb_buf(SKB才是套接字的缓冲区)
  10. Linux启动跟windows启动,Windows,Linux启动机制简介