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 缓存实战——缓存、数据库一致性问题分析与解决方案

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

基于计算思维的python程序设计王彬丽期末考试题库_基于计算思维的程序设计类课程教学实践...

基于计算思维的程序设计类课程教学实践滕剑锋王玉锋王猛刘二林【摘要】摘要很多专业开设了程序设计类课程。如何在该课程教学中培养学生的创新能力是大家普遍考虑的问题。计算思维的提出对于解决该问题具有重要的指导意义。在此背景下,我们针对程序设计类课程的教学…

Java 多线程 —— AQS 详解

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

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

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

Java常用设计模式——观察者模式

导航一、行为描述二、角色关系三、代码示例一、行为描述 观察者会观察特定对象的状态变化,一旦状态有所变化或产生特定条件,被观察对象会通知给观察者, 而观察者则会依据通知信息采取特定处理措施。 举个例子,公司接到了一个大项…

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缓存架构…

蓝牙连接不上车要hfp_汽车上hfp是什么意思

汽车上hfp的全称是Hands-free-Profile,是一款让蓝牙设备控制电话,实现接听、挂断、拒接、语音拨号等功能的软件。hfp车载蓝牙功能使用上十分方便,可以有效地降低安全事故,在手机和车载蓝牙连接之后,在打电话的状况下可…

python3中的 input函数_Python3中的input函数

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

python转二进制字符串_python如何将二进制串(UTF-8)转换为字符串?

已知一个二进制串(UTF-8编码格式)列表(每一项为一字节8bit):b[01010000, 01111001, 01110100, 01101000, 01101111, 01101110, 11100101, 10100100, 10100111, 11100110, 10110011, 10010101]#即字符串"Python大法"如何将其转换为字符串呢?string ""for …

python中reshape_Numpy之reshape()使用详解

如下所示:Numpy中reshape的使用方法为:numpy.reshape(a, newshape, orderC)参数详解:1.a: type:array_like(伪数组,可以看成是对数组的扩展,但是不影响原始数组。)需要reshape的array2.newshape:新的数组新形状应与原形状兼容。如…

vue 手机端路由切换滑动_vue移动端router-view嵌套实现底部导航切换

路由使用 vue-router组件库使用 vue-ydui效果图:登录.png主界面-首页.png主界面-办事大厅.png项目结构图片.png大体流程图片.png路由代码import Vue from vueimport Router from vue-routerimport home from ../page/homeimport office from ../page/officeimport m…

bs4 乱码_Python BeautifulSoup中文乱码问题的2种解决方法

解决方法一:使用python的BeautifulSoup来抓取网页然后输出网页标题,但是输出的总是乱码,找了好久找到解决办法,下面分享给大家首先是代码复制代码 代码如下:from bs4 import BeautifulSoupimport urllib2url //www.jb51.net/page urllib2.urlopen(url)soup Beaut…

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

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

最大值_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 …