MySQL 基础 ————事务与隔离级别总结

引言

 

在处理并发读或写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题:

共享锁(shared lock)和排它锁(exclusive lock),也叫读锁(read lock)和写锁(write lock)

读锁是共享的,也就是互相不阻塞。多个客户在同一时刻可以同时读取同一个资源,互不干扰。

写锁是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,只有这样,才能保证在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。 

在实际数据库系统中,每时每刻都在发生锁定,当某个用户在修改某一部分数据时,MySQL 会通过锁定防止其他用户读取同一数据。

一、事务的概念

事务主要针对查询以外的其他几项操作:插入、更新、删除,将多条SQL合并到一个执行单元中,要么全部执行成功,要么全部回滚。MySQL的TCL 事务控制语言,就是为事务而设计,接下来我们来总结一下。

二、事务的 ACID 属性

1、原子性

原子性是指事务是一个不可分割的工作单元,不可分割,意味着要么全部执行,要么全部回滚。

2、一致性

事务必须使数据库从一个一致状态,变换到另一个一致状态。

3、隔离性

事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是不可见的。并发的多个事务之间互不干扰。

4、持久性

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

三、事务操作的演示

3.1 事务提交变量:autocommit

MySQL控制事务提交的变量叫做'autocommit',可以通过如下语句进行查看:

SHOW VARIABLES LIKE 'autocommit';

默认情况下是开启的,即执行SQL后会自动提交事务。如果希望手动提交事务,需要将ON —> OFF。但这种方法只在当前会话中有效,只要新开一个连接或是MySQL会话,就会恢复自动提交事务:

SET autocommit = 0;

3.2 开启事务和提交事务

通过 set autocommit = 0 即表示开启显式事务(默认是隐式事务),其实开启事务的语句是下面这句,不过一般都会省略:

START TRANSACTION;

开启事务后,我们就可以执行多条SQL,一般是 insert、update、delete 语句等,且不会自动提交。

当我们执行完这些SQL,想提交的时候,可以执行下面语句:

COMMIT; -- 提交事务
ROLLBACK; -- 回滚事务

注意:事务中的语句仅支持 select、insert、update、delete,这四种,其他的如 create 等是不支持的。

3.3 案例演示

假设现在有两个会话连接到MySQL数据库,第一个连接关闭事务自动提交:

先查询 emp 表的一条记录,准备后续的更新操作:

将名称更新为'张三丰':

切换到另一个会话,查看该条记录,可以看到记录还没有任何变化:

切换回第一个会话,提交事务:

此时再切换到另一个事务查看该条记录,已经变成了 “张三丰”:

四、并发事务与隔离级别

对于同时运行的多个事务,当这些事务访问数据库中相同的数据时,如果没有采取必要的隔离机制,就会导致各种并发问题。

1、脏读:对于任意两个事务:T1、T2。T1读取了已经被T2 更新但还没有提交的字段之后,若 T2 回滚, T1 读取到的内容是临时且无效的。读取了事务执行过程中的中间数据

2、不可重复读:对于两个事务 T1、T2 。T1 读取了一个字段,然后T2 更新了该字段之后,T1 再次读取同一个字段,值就不同了。在同一个事务中,受其他事务更新影响,两次读取的数据不一致

3、幻读:对于两个事务 T1、T2。T1 读取一张表,然后 T2 在该表中插入了一些新的记录。之后,如果 T1 再次读取同一张表,就会多出几行。在同一个事务中,受其他事务插入删除影响,两次读取的记录数量有变化

4.1 隔离级别介绍

为了针对上述的三种并发问题,每种数据库都会有自己的一套隔离级别,它描述了一个事务与其他事务隔离的程度。数据库规定了多种事务隔离级别,不同的隔离级别对应不同的干扰程度,隔离级别越高,数据一致性就越好,但相应的,并发性就越差

数据库提供四种隔离级别:读未提交、读已提交、可重复读(MySQL默认)、串行化。Oracle 仅支持读已提交和串行化,默认是读已提交。MySQL则四种全部支持,默认是可重复读

4.2 READ-UNCOMMITTED : 读未提交

该隔离级别允许读取未被其他事务提交的变更,脏读、不可重复读和幻读的问题都会出现

4.3 READ-COMMITTED: 读已提交

只允许读取已经被其他事务提交的变更,可避免脏读,但不可重复读和幻读问题仍然会出现。

4.4 REPEATABLE-READ : 可重复读

确保事务内可以多次从一个字段中读取相同的值,在这个事务持续期间禁止其他事务对这个字段进行更新,可以避免脏读和不可重复度,但幻读问题仍然存在。

4.5 SERIALIZABLE : 串行化事务

确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新、删除等操作,所有并发问题都可以解决,但性能非常低

4.6 查看、设置隔离级别

通过 SELECT 子句,查看隔离级别:

SELECT @@tx_isolation;

通过 SET 子句,设置隔离级别:

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -- SESSION 可省略

注意,上述方法设置的隔离级别仅适用于当前连接,如果希望设置全局的隔离级别,可以使用 GLOBAL 关键字:

SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;

GLOBAL 关键字可以保证所有新的连接都会使用设置的隔离级别,但是旧的连接如果没有关闭,依然会采用原来的隔离级别。另外,全局隔离级别设置仅针对本次MySQL服务有效,如果MySQL服务重启,则依然是默认的隔离级别,除非在配置文件中改变MySQL默认隔离级别。

4.7 隔离级别与并发问题的关系

脏读不可重复读幻读
READ-UNCOMMITTED出现出现出现

READ-COMMITTED

(Oracle默认)

解决出现出现

REPEATABLE-READ

(MySQL默认)

解决解决出现
SERIALIZABLE解决解决解决

以上就是关于隔离级别与并发问题的总结和归纳。

重点是事务的ACID 属性三个并发问题的定义四种隔离级别的定义四种隔离级别与三个并发问题的关系,以及如何查看数据库的隔离级别,设置数据库的隔离级别。

4.8 事务日志

事务日志可以帮助提高事务的效率。

使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。

事务日志采用的是追加方式,因此写日志的操作是磁盘上一小块区域的顺序IO,而不是存储数据时的随机IO,所以采用事务日志相对较快。

事务日志持久以后,内存中被修改的数据可以在后台慢慢刷回到磁盘。

目前大多数存储引擎都是这样实现的,通常称之为“预写式日志(Write-Ahead Logging)”,修改数据需要写两次磁盘

如果数据的修改已经记录到事务日志并持久化,但数据本身还没写回磁盘,如果此时系统崩溃,那么存储引擎在重启时是可以自动恢复这部分修改的数据的。但具体的恢复方式可能不尽相同。

五、锁粒度

一种提高共享资源并发性的的方式就是让锁定对象更有选择性,尽量只锁定需要修改的部分数据。更理想的方式是,只对会修改的数据片进行精确的锁定。但是锁的数量也会增大系统的开销。

所谓锁策略,就是在锁的开销和数据的安全性之间寻求平衡,这种平衡当然也会影响到性能。大多数商业数据库没有提供更多的选择,一般都是在表上施加行级锁,并以各种复杂的方式来实现,以便在锁比较多的情况下尽可能的提供更好的性能。

MySQL则提供了多种选择。每种MySQL存储引擎都可以实现自己的锁策略和锁粒度。

在存储引擎的设计中,锁管理是个非常重要的决定。

5.1 表锁

表锁是MySQL最基本的锁策略,并且是开销最小的锁策略。用户在对表进行写操作(插入、删除、更新)前,需要先获得写锁,这会阻塞其他用户对该表的所有读和写操作。只有没有写锁时,其它读取的用户才能获得读锁,读锁之间是不相互阻塞的

在特定情况下,表锁也有良好的性能。例如,READ LOCAL表锁支持某种类型的并发写操作。

写锁比读锁有更高的优先级。一个写锁请求可以插入到锁队列中读锁的前面,反之读锁则不能插入到写锁的前面。

存储引擎可以管理自己的锁,如InnoDB的行锁,但MySQL在某些情景下会使用表锁,从而忽略存储引擎的锁机制。例如,MySQL会为ALTER TABLE之类的语句使用表锁,忽略存储引擎的锁机制。

5.2 行锁

行级锁可以最大程度地支持并发处理,但同时锁开销也是最大的。行级锁只在存储引擎层实现,如InnoDB、XtraDB等,而MySQL服务器层没有实现。

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

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

相关文章

32f407tim4时钟源频率_慎重选择时钟发生器,别让这俩指标影响你的ADC 「图片」...

系统设计师通常侧重于为应用选择最合适的数据转换器,在向数据转换器提供输入的时钟发生器件的选择上往往少有考虑。然而,如果不慎重考虑时钟发生器的相位噪声和抖动性能,数据转换器动态范围和线性度性能可能受到严重的影响。系统考虑因素采用…

Spring —— IoC 容器详解

引言 本篇博客总结自官网的《The IoC Container》,其中会结合王富强老师的《Spring揭秘》融入自己的语言和理解,争取通过这一篇文章彻底扫除spring IOC的盲区。 本文介绍什么是 IoC 容器,什么是 Bean,依赖,Bean Defi…

nvidia控制面板点了没反应win7_win7系统Nvidia控制面板怎么设置?

许多用户不知道Nvidia控制面板怎么设置?那么Nvidia控制面板如何设置呢?其实设置的方法很简单。接下来,小编就把Nvidia控制面板设置的方法告诉大家。1、首先在桌面右键点击选择NVIDIA控制面板。2、显卡的设置性能肯定是要高好了,所以在性能设置方面&…

切割 字符串_web前端如何使用字符串

一、字符串概述定义:字符串就是用单引号或者双引号包裹起来的,零个或多个排列在一起的字符。例如:’javascript‘, “”, “345” , ’9-11a$‘, “xiao_yuanLian”嵌套:字符串可以嵌套。在单引号包裹的字符串内部,应该…

Redis 缓存实战——缓存、数据库一致性问题分析与解决方案

引言 缓存与数据库一致性的问题自从出现了缓存概念后就一直被提及,它是一个缓存方案的先天缺陷,只要存在缓存,就势必会讨论缓存与数据库一致性的问题。 一致性问题还广泛存在于各种分布式存储场景中,如主从一致性等等。 本篇博…

Java 多线程 —— AQS 详解

引言 AQS 是AbstractQuenedSynchronizer 的缩写,抽象的队列式同步器,它是除了java自带的synchronized关键字之外的锁机制。是 JUC 下的重要组件。 相关产物有:ReentrantLock、CountDownLatch、Semaphore、ReadWriteLock等。 一、AQS的设计…

的主机名_如何在Mac 上更改电脑的名称或本地局域网主机名?

我们知道,一台电脑有其设定的具体名称,电脑的名称和本地主机名用于在本地网络上识别您的电脑。当我们需要自定义电脑名称或本地局域网主机名时,则需要对其进行更改。那我们该如何更改呢?有需要的小伙伴们快和小编一起来看看吧~更改…

dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单

前言这几天又拾起老本行,复习复习Android,才发现忘的差不多了,上午做了一个小Demo,配合Scroller做了一个轮播图,效果如下,但是不知为何,录制的GIF成这样,凑乎一下看看。原理是继承Vi…

JVM——CPU缓存架构与Java 内存模型

导航一、CPU缓存架构与一致性协议1.1 CPU缓存架构1.2 缓存行与伪共享问题1.3 MESI 缓存一致性协议1.4 伪共享的解决办法二、JMM Java 内存模型2.1 JMM 简介2.2 原子性、可见性、有序性2.3 八大内存交互操作2.4 happens-before 原则一、CPU缓存架构与一致性协议 1.1 CPU缓存架构…

白噪声检测_科学家尝试用智能扬声器的白噪声来监测婴儿的呼吸运动

华盛顿大学的一支研究团队,刚刚介绍了他们开发的一种新型智能扬声器技术。这种设备能够借助白噪声来安抚熟睡的婴儿,并监测他们的呼吸和运动。具体说来是,通过智能扬声器发出的白噪声,原型设备能够将之与生命体征监测仪的数据相匹…

最大值_285期 博最大值2路,已经箭在弦上!

往期数据P-5掉码 跨度 和尾 012断路 余数和 位数86072 1 8 4 200 断1路2 5 对214对 双双双79703 0 2 3 101 断2路2 4 对215对 单单单62386 0 4 1 020 断1路2 4 错216对 双双单71903 0 8 7 110 断2路2 5 错217对 单单单64838 0 4 8 012 来3路3 4 错218对 双双双02052 0 2 2 020 …

商品领域ddd_为 Gopher 打造 DDD 系列:领域模型-资源库

前言: 作为领域模型中最重要的环节之一的Repository,其通过对外暴露接口屏蔽了内部的复杂性,又有其隐式写时复制的巧妙代码设计,完美的将DDD中的Repository的概念与代码相结合!Repository资源库通常标识一个存储的区域…

mysql5.7主从全备恢复_Mysql5.7—运维常用备份方式(超全)

小生博客:http://xsboke.blog.51cto.com小生 Q Q:1770058260-------谢谢您的参考,如有疑问,欢迎交流一、 Mysqldump备份结合binlog日志恢复使用mysqldump进行全库备份,并使用binlog日志备份,还原时&#xf…

docker 运行容器_Docker之运行 Django 容器

首先此篇笔记默认你已经安装好了 Docker,并了解 Docker 的基础概念,诸如镜像、容器、以及他们之间的关系等。如果不太了解,等我回头了解清楚以后,可以再写一篇文章阐述一下。(狗头当然,对于这篇文章&#x…

mysql8.0与mysql7.0_MySQL 5.7 vs 8.0,哪个性能更牛?

测试mysql5.7和mysql8.0分别在读写,选定,只写模式下不同并发时的性能(tps,qps)最早测试使用版本为mysql5.7.22和mysql8.0.15sysbench测试前先重启mysql服务,并清除os的缓存(避免多次测试时命中缓存)每次进行测试都是新生成测试数据…

springmvc使用requestmapping无法访问控制类_研究人员称人类使用的新烟碱类杀虫剂让蜜蜂无法入睡...

来自布里斯托尔大学的科学家进行了研究,显示常见的杀虫剂可以阻止蜜蜂和苍蝇睡个好觉。就像人类一样,许多昆虫也需要睡眠才能正常工作。然而,如果它们接触过新烟碱类杀虫剂,它们的睡眠就会受到影响,新烟碱类杀虫剂是一…

linux 监控mysql脚本_Linux系统MySQL主从同步监控shell脚本

操作系统:CentOS系统目的:定时监控MySQL数据库主从是否同步,如果不同步,记录故障时间,并执行命令使主从恢复同步状态1、创建脚本文件vi /home/crontab/check_mysql_slave.sh #编辑,添加下面代码#!/bin/sh…

python协成_Python协程(上)

几个概念:event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。coroutine 协程:协程对象,指一个使用async关键字定义的函数&#…

js父元素获取子元素img_css,前端_父标签div中包含一个子元素img标签,子元素div标签,为什么img要加上浮动,子元素div才会处于正常位置?,css,前端 - phpStudy...

父标签div中包含一个子元素img标签,子元素div标签,为什么img要加上浮动,子元素div才会处于正常位置?dom结构如图img加上float 子元素div显示正常。不加float div显示错位。附上我写的一个dome测试用的,大家可本地看下究…

android运营商获取本机号码_一键登录已成大势所趋,Android端操作指南来啦!

根据极光(Aurora Mobile)发布的《2019年Q2移动互联网行业数据研究报告》,2019年第二季度,移动网民人均安装APP总量已达56款。面对如此繁多的APP,想在用户的手机中占据一席之地,移动开发者们就不得不努力提升用户体验。而现实却是&…