MySQL事务与MVVC

一、ACID特性

数据库管理系统中**事务(transaction)**的四个特性(分析时根据首字母缩写依次解释):原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。(执行单个逻辑功能的一组指令或操作称为事务)

1. 原子性

原子性是指事务是一个不可再分割的工作单元,事务中的操作要么都发生,要么都不发生。

可采用“A向B转账”这个例子来说明解释

在DBMS中,默认情况下一条SQL就是一个单独事务,事务是自动提交的。只有显式的使用start transaction开启一个事务,才能将一个代码块放在事务中执行。

2. 一致性

一致性是指在事务开始之前和事务结束以后数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性

如A给B转账,不论转账的事务操作是否成功,其两者的存款总额不变(这是业务逻辑的一致性,至于数据库关系约束的完整性就更好理解了)。

保障机制(也从两方面着手):数据库层面会在一个事务执行之前和之后,数据会符合你设置的约束(唯一约束,外键约束,check约束等)和触发器设置;此外,数据库的内部数据结构(如 B 树索引或双向链表)都必须是正确的。业务的一致性一般由开发人员进行保证,亦可转移至数据库层面。

3. 隔离性

多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。

在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据

事务最复杂问题都是由事务隔离性引起的。完全的隔离性是不现实的,完全的隔离性要求数据库同一时间只执行一条事务,这样会严重影响性能。

关于隔离性中的事务隔离等级(事务之间影响),参见相应博文

4. 持久性

这是最好理解的一个特性:持久性,意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。(完成的事务是系统永久的部分,对系统的影响是永久性的,该修改即使出现致命的系统故障也将一直保持)

write ahead logging:SQL Server中使用了WAL(Write-Ahead Logging)技术来保证事务日志的ACID特性,在数据写入到数据库之前,先写入到日志,再将日志记录变更到存储器中。

二、事务的4种隔离级别

数据库事务的隔离级别有4种,由低到高分别为Read uncommitted 、Read committed 、Repeatable read 、Serializable 。而且,在事务的并发操作中可能会出现脏读,不可重复读,幻读。下面通过事例一一阐述它们的概念与联系。

Read uncommitted

读未提交,顾名思义,就是一个事务可以读取另一个未提交事务的数据。

事例:老板要给程序员发工资,程序员的工资是3.6万/月。但是发工资时老板不小心按错了数字,按成3.9万/月,该钱已经打到程序员的户口,但是事务还没有提交,就在这时,程序员去查看自己这个月的工资,发现比往常多了3千元,以为涨工资了非常高兴。但是老板及时发现了不对,马上回滚差点就提交了的事务,将数字改成3.6万再提交。

分析:实际程序员这个月的工资还是3.6万,但是程序员看到的是3.9万。他看到的是老板还没提交事务时的数据。这就是脏读。

那怎么解决脏读呢?Read committed!读提交,能解决脏读问题。

Read committed

读提交,顾名思义,就是一个事务要等另一个事务提交后才能读取数据。

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(程序员事务开启),收费系统事先检测到他的卡里有3.6万,就在这个时候!!程序员的妻子要把钱全部转出充当家用,并提交。当收费系统准备扣款时,再检测卡里的金额,发现已经没钱了(第二次检测金额当然要等待妻子转出金额事务提交完)。程序员就会很郁闷,明明卡里是有钱的…

分析:这就是读提交,若有事务对数据进行更新(UPDATE)操作时,读操作事务要等待这个更新操作事务提交后才能读取数据,可以解决脏读问题。但在这个事例中,出现了一个事务范围内两个相同的查询却返回了不同数据,这就是不可重复读。

那怎么解决可能的不可重复读问题?Repeatable read !

Repeatable read

重复读,就是在开始读取数据(事务开启)时,不再允许修改操作

事例:程序员拿着信用卡去享受生活(卡里当然是只有3.6万),当他埋单时(事务开启,不允许其他事务的UPDATE修改操作),收费系统事先检测到他的卡里有3.6万。这个时候他的妻子不能转出金额了。接下来收费系统就可以扣款了。

分析:重复读可以解决不可重复读问题。写到这里,应该明白的一点就是,不可重复读对应的是修改,即UPDATE操作。但是可能还会有幻读问题。因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。

什么时候会出现幻读?

事例:程序员某一天去消费,花了2千元,然后他的妻子去查看他今天的消费记录(全表扫描FTS,妻子事务开启),看到确实是花了2千元,就在这个时候,程序员花了1万买了一部电脑,即新增INSERT了一条消费记录,并提交。当妻子打印程序员的消费记录清单时(妻子事务提交),发现花了1.2万元,似乎出现了幻觉,这就是幻读。

那怎么解决幻读问题?Serializable!

Serializable 序列化

Serializable 是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

值得一提的是:大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。

三、MYSQL MVCC 实现机制

3.1 MVVC简介

什么是MVCC

MVCC是一种多版本并发控制机制。

MVCC是为了解决什么问题

  • 大多数的MYSQL事务型存储引擎,如,InnoDB,Falcon以及PBXT都不使用一种简单的行锁机制.事实上,他们都和MVCC–多版本并发控制来一起使用.
  • 大家都应该知道,锁机制可以控制并发操作,但是其系统开销较大,而MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销.

MVCC实现

MVCC是通过保存数据在某个时间点的快照来实现的. 不同存储引擎的MVCC. 不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制.

3.2 MVCC 具体实现分析

下面,我们通过InnoDB的MVCC实现来分析MVCC使怎样进行并发控制的. InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的,这两个列,分别保存了这个行的创建时间,一个保存的是行的删除时间。这里存储的并不是实际的时间值,而是系统版本号(可以理解为事务的ID),每开始一个新的事务,系统版本号就会自动递增,事务开始时刻的系统版本号会作为事务的ID.下面看一下在REPEATABLE READ隔离级别下,MVCC具体是如何操作的.

简单的小例子

create table yang( id int primary key auto_increment, name varchar(20));假如系统的版本号从1开始

INSERT

InnoDB为新插入的每一行保存当前系统版本号作为版本号. 第一个事务ID为1;

start transaction;
insert into yang values(NULL,'yang') ;
insert into yang values(NULL,'long');
insert into yang values(NULL,'fei');
commit;

对应在数据中的表如下(后面两列是隐藏列,我们通过查询语句并看不到)

idname创建时间(事务ID)删除时间(事务ID)
1yang1undefined
2long1undefined
3fei1undefined

SELECT

InnoDB会根据以下两个条件检查每行记录: a.InnoDB只会查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的. b.行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除. 只有a,b同时满足的记录,才能返回作为查询结果.

DELETE

InnoDB会为删除的每一行保存当前系统的版本号(事务的ID)作为删除标识. 看下面的具体例子分析: 第二个事务,ID为2;

start transaction;
select * from yang;  //(1)
select * from yang;  //(2)
commit;

假设1

假设在执行这个事务ID为2的过程中,刚执行到(1),这时,有另一个事务ID为3往这个表里插入了一条数据; 第三个事务ID为3;

start transaction;
insert into yang values(NULL,'tian');
commit;

这时表中的数据如下:

idname创建时间(事务ID)删除时间(事务ID)
1yang1undefined
2long1undefined
3fei1undefined
4tian3undefined

然后接着执行事务2中的(2),由于id=4的数据的创建时间(事务ID为3),执行当前事务的ID为2,而InnoDB只会查找事务ID小于等于当前事务ID的数据行,所以id=4的数据行并不会在执行事务2中的(2)被检索出来,在事务2中的两条select 语句检索出来的数据都只会下表:

idname创建时间(事务ID)删除时间(事务ID)
1yang1undefined
2long1undefined
3fei1undefined

假设2

假设在执行这个事务ID为2的过程中,刚执行到(1),假设事务执行完事务3后,接着又执行了事务4; 第四个事务:

start   transaction;  
delete from yang where id=1;
commit;

此时数据库中的表如下:

idname创建时间(事务ID)删除时间(事务ID)
1yang14
2long1undefined
3fei1undefined
4tian3undefined

接着执行事务ID为2的事务(2),根据SELECT 检索条件可以知道,它会检索创建时间(创建事务的ID)小于当前事务ID的行和删除时间(删除事务的ID)大于当前事务的行,而id=4的行上面已经说过,而id=1的行由于删除时间(删除事务的ID)大于当前事务的ID,所以事务2的(2)select * from yang也会把id=1的数据检索出来.所以,事务2中的两条select 语句检索出来的数据都如下:

idname创建时间(事务ID)删除时间(事务ID)
1yang14
2long1undefined
3fei1undefined

UPDATE

InnoDB执行UPDATE,实际上是新插入了一行记录,并保存其创建时间为当前事务的ID,同时保存当前事务ID到要UPDATE的行的删除时间.

假设3

假设在执行完事务2的(1)后又执行,其它用户执行了事务3,4,这时,又有一个用户对这张表执行了UPDATE操作: 第5个事务:

start  transaction;
update yang set name='Long' where id=2;
commit;

根据update的更新原则:会生成新的一行,并在原来要修改的列的删除时间列上添加本事务ID,得到表如下:

idname创建时间(事务ID)删除时间(事务ID)
1yang14
2long15
3fei1undefined
4tian3undefined
2Long5undefined

继续执行事务2的(2),根据select 语句的检索条件,得到下表:

idname创建时间(事务ID)删除时间(事务ID)
1yang14
2long15
3fei1undefined

还是和事务2中(1)select 得到相同的结果.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java在坐标系中找出距离最近的点

在有限点中找出距离最近的点,要求用二维数组且为浮点型(Double)编写,编写一个distance方法计算距离在主方法中来比较 输入:输入点的个数和坐标点(不需要括号和逗号) 8-1 3 -1 -1 1 1 2 0.5 2 -1 3 3 4 2 …

使用Navicat将数据从Excel导入到MySQL数据库

数据库中的表已经建好了,现在要将数据从Excel导入 要求:Excel中要有一行为字段名(可以与数据表中的字段名顺序不一样) 具体步骤 1、右键单击表,选择 导入向导 2、选择数据导入格式,然后点击下一步 3…

什么是超文本 超链接 HTML有什么特点,什么是超文本?什么是超链接?

什么是超文本?什么是超链接?什么是HTML?简而言之:超文本包含超链接,html是表示超文本的语言,超链接是超文本内的元素超文本包含很多元素,比如文字、图片、链接到其他超文本的链接(超链接)等。超…

flatMap(Collection::Stream)用法

Map<key, List a> 取出Map的List a map.values().stream().flatMap(Collection::stream).collect(Collectors.toList());

html5 a-z字母排序,Mint UI实现A-Z字母排序的城市选择列表

本文实例为大家分享了Mint Ul实现A-Z字母排序的城市选择列表的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下效果图如下&#xff1a;项目文件存放路径图&#xff1a;所有代码如下&#xff1a;import city from "../assets/json/city"//导入所有城市的JSON…

Geometry几何结构与WKT空间坐标计算缓冲距离模型构建

geometry&#xff0c;英语单词&#xff0c;名词&#xff0c;意思是“几何学几何结构”。 http://www.baike.com/wiki/WKTWKT&#xff0c;是一种文本标记语言&#xff0c;用于表示矢量几何对象、空间参照系统及空间参照系统之间的转换。它的二进制表示方式&#xff0c;亦即WKB(…

html5开发之ios屏幕适配,iOS开发屏幕尺寸以及屏幕适配等问题(转载内容)

原帖地址&#xff1a;http://blog.csdn.net/phunxm/article/details/42174937/仅供我个人收藏学习&#xff0c;原博主如不同意请联系qq651263878进行删除&#xff0c;在此表示感谢以及歉意。1.iPhone尺寸规格后续上市的iPhone7以及iPhone7plus 与六代相同1 inch 2.54cm 25.4…

flink checkpoint 恢复_Flink解析 | Apache Flink结合Kafka构建端到端的ExactlyOnce处理

周凯波(宝牛)阿里巴巴技术专家&#xff0c;四川大学硕士&#xff0c;2010年毕业后加入阿里搜索事业部&#xff0c;从事搜索离线平台的研发工作&#xff0c;参与将搜索后台数据处理架构从MapReduce到Flink的重构。目前在阿里计算平台事业部&#xff0c;专注于基于Flink的一站式计…

Java通过ftl模板导出word最详细教程

首先用office建一个word文档 参数写自己查询出来的字段&#xff0c;我在这里房里图片是方便找到位置替换为64位编码 模板创建好之后&#xff0c;另存为Word 2003 XML文档(*.xml) 存储为别的可能会报错&#xff0c;我只用这一种 存储为xml之后千万不要用word打开&#xff0c;最…

封装html ui 控件,聊聊前端 UI 组件:组件设计

本文首发于欧雷流。由于我会时不时对文章进行补充、修正和润色&#xff0c;为了保证所看到的是最新版本&#xff0c;请阅读原文。在本系列文章《聊聊前端 UI 组件&#xff1a;组件体系》中初步说明了 UI 组件的架构设计&#xff0c;本文将在此基础上进一步展开说说那篇文章中一…

live555推流rtsp_Hi3518 RTSP推流

1、openssl编译下载地址:http://distfiles.macports.org/openssl/解压后进入源码根路径执行./config no-asm no-async --prefix/home/chenyc/project/hi3518e/Hi3518E_SDK_V1.0.3.0/armlib/openssl --cross-compile-prefixarm-hisiv300-linux-#打开生成的makefile 删除-m64 在…

怎么两边同时取ln_男生“两边铲光”发型out了?试试这4款吧,剪完清爽又帅气...

发型对于男生来说是特别重要的&#xff01;女生可以通过化妆来让自己变得更完美&#xff0c;而男生想要改变自己的形象&#xff0c;是不敢轻易化妆的&#xff0c;只有通过改变自己的发型&#xff0c;才能更好地展现自己的魅力。现下男生最流行的发型&#xff0c;莫过于“两边铲…

ionic 修改组件默认样式_开源Magpie:组件库详解

开源项目专题系列(八)1.开源项目名称&#xff1a;magpie_fly2.github地址&#xff1a;https://github.com/wuba/magpie_fly3.简介&#xff1a;magpie_fly 是58集体出品组件库&#xff0c;统一管理日常开发中的基础组件及高阶组件&#xff0c;并提供了相对友好的方式介绍组件的具…

口袋之旅html5超强账号,口袋之旅特攻排行榜 强大的绝对能力

历史上是在金银版分了精灵的特攻物攻&#xff0c;在宝石版分了技能的特攻物攻&#xff0c;让很多精灵和技能得以重生。口袋之旅采用的是第二世代的精灵加第三世代的技能分类&#xff0c;于是特攻手也成为了一个需要挑选的部分&#xff0c;本文继续为你缩小挑选范围。特攻种族值…

使用ftl生成word

背景&#xff1a;根据word模板下载word。word里面需要填充数据&#xff0c;格式是固定的。首先在word中给数据起个变量名称 需要更换的数据改成${变量名!}&#xff0c;必须是英文的&#xff0c;加感叹号是为了防止null&#xff0c;如果数据是null&#xff0c;文档下载下来后会直…

什么叫做项目孵化_蓝莓孵化营12进5争夺战,项目人绽放自我不留遗憾

国内首档互联网职业竞技励志节目《蓝莓孵化营》&#xff0c;今晚22点在浙江卫视播出第十一期。本期节目中&#xff0c;第三事业群的12组项目人将为最终的5张终极考核入场券展开争夺。这一次&#xff0c;他们比拼的是以“2020”为主题的短视频&#xff0c;每一组项目人都拼尽了自…

七台河计算机网络工程专业,网络工程本科专业介绍

网络工程本科专业介绍网络工程专业是教育部第二类特色专业&#xff0c;比较热门&#xff0c;竞争力较大&#xff0c;考生报考此专业的时候要慎重。网络工程本科就业前景本专业的就业前景不错&#xff0c;学生可从事各级各类企事业单位的企业办公自动化处理、计算机安装与维护、…

Java实体类不要使用基本类型_为何封装javabean时,成员变量一律都不用基本类型

Java实体类不要使用基本类型 记录一下&#xff0c;在项目中因为基本类型&#xff0c;所产生的bug 包装类&#xff1a;8种基本类型的包装类 应用场景&#xff1a;数据库建立实体映射多用包装类 这两句话是重点&#xff1a;就是建立实体类禁止使用基本数据量类型&#xff01;…

一开机就提示脱机工作_「华为手机维修自学教程」华为手机的开机触发电路 华为维修技巧...

谈谈华为的开机触发电路华为这段时间的新闻不少&#xff0c;大家应该都有说了解。华为的强大意味着华为手机的维修市场越来越大。从事维修的朋友们你们准备好了吗&#xff1f;今天给大家说一说&#xff0c;华为手机的开机触发电路。修苹果手机的朋友大家都知道&#xff0c;电源…

html怎么保存曲奇,自制曲奇饼能保存多久 这些存放方法你懂吗

来源:站酷作者:Wandzilak虽然市场上的饼干种类很多&#xff0c;而且吃起来也感觉十分香&#xff0c;但是这些食品一般添加了比较多的防腐剂膨松剂&#xff0c;多吃度身体健康不是很好。因此很多人都喜欢自己在家里制作饼干&#xff0c;其中曲奇饼干就是很多人都喜欢制作的饼干之…