数据库事务隔离级别
前几天项目上合作公司的系统出现了一次死锁,突然想到由于近几年开发设计的系统并发用户比较少,很久没有碰到过死锁了,因此对死锁的概念也比较生疏了,需要温习一下。
事务
先从最基本的概念开始,事务、及其ACID特性。
事务的概念就用一句话概括:事务中的SQL语句要么全部执行成功,要么全部执行失败。
Atomicity:原子性,一个事务必须被视为不可分割的工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚。对于一个事务来说,不能只执行其中的一部分操作,这就是事务的原子性。
Consistency:一致性,事务可以确保数据总是从一个一致性状态转换到另一个一致性状态。
Isolation:隔离性,事务隔离性的目的是要确保一个事务所做的修改在最终提交之前,对其他事务是不可见的。这一点其实是很难做到的,所以才有了iso level,隔离级别的概念。
Durability:持久性,一旦事务提交,修改就会永久保存在数据库中。
隔离级别
SQL标准定义了四种隔离级别:
READ UNCOMMITTED(未提交读)
事务中的修改即使没有提交,其他事务中也是能看见的。事务能够读取未提交数据也被称之为“脏读”(dirty read)。这个级别会导致很多问题,从性能上来说,READ UNCOMMITTED不对比其他级别好太多。但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。
*** READ COMMITTED(提交读) ***
大部分数据库(SQL Server/Oracle等)默认的隔离级别,但Mysql不是。一个事务开始后,只能看到其他事务已经提交的修改。READ COMMITTED避免了脏读,但是READ COMMITTED不可重复读(nonrepeatable read),因为在一个事务中两次执行同样的查询,可能会读到不一样的结果。
REPEATABLE READ(可重复读)
可重复读确保了在一个事务中多次读取同样记录的结果是一致的。但是在理论上REPEATABLE READ还是无法解决另外一个幻读(phantom read)的问题。幻读指的是某个事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围内的数据时,会产生幻行(phantom row)。InnoDB和XtraDB存储引擎通过引入MVCC解决了幻读问题。
可重复读是MySql默认的隔离级别。
SERIALIZABLE(串行化)
最高隔离级别,通过强制事务串行执行避免幻读问题。简单来说RERIALIZABLE会在读取的每一行数据上加锁,所以可能会导致大量的超时和锁争夺问题,实际应用中很少用这个隔离级别。

死锁
死锁指的是两个或多个事务在统一资源上的相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
当多个事务试图以不同顺序锁定资源时,就可能产生死锁,多个事务同时锁定同一个资源时,也可能产生死锁。
比如,事务一:
start transaction;
update stock set price=1.2 where id=3;
update stock set price=1.5 where id=4;
commit;
事务二:
start transaction;
update stock set price=1.2 where id=4;
update stock set price=1.5 where id=3;
commit;
如果事务一执行了第一条update语句、锁定了第一条数据、事务二也执行了第一条update语句、锁定了第一条数据,此时两个事务准备执行第二条语句是发现已经被对方锁定,彼此等待对方释放锁资源、同时又持有对方等待的锁资源,这样就陷入了死循环,造成死锁。
死锁发生后必须有第三方介入才可能解除。比如大部分的数据库都设置了等待的timeout时长,超过该时长后事务会主动放弃等待(InnoDB引擎将持有最少行级排它锁的事务回滚)、rollback事务。
死锁是事务性数据库系统中不可避免的现象,我们可以认为死锁其实是数据一致性的一种保护性措施,但是我们在设计应用的时候,还是要在充分理解死锁底层逻辑的前提下,尽可能避免死锁的发生。
MVCC
MVCC是multi-version concurrency control的缩写,意思是多版本并发控制。多版本并发控制是尽可能避免加锁操作而实现数据库的ACID,因此开销更低。
MVCC是通过保存数据在某一个时间点的快照来实现的,也就是说,不管执行多长时间,每个事务看到的数据是一致的。根据事务开始时间的不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
MVCC没有统一的实现标准,不同存储引擎的MVCC实现是不同的。
InnoDB的MVCC实现的简化版行为:
InnoDB的每行记录后面保存两个隐藏的列,一个保存行的创建时间、一个保存行的删除时间。但是实际记录的并不是时间,而是版本号。
没开始一个新的事务,版本号会自动递增,事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行版本号作比较。
在REPEATABLE READ隔离级别下:
SELECT操作,InnoDB会以下两个条件检查每行记录:
- 只查找版本早于当前事务版本号的数据行(也就是,行的系统版本号小于等于事务的系统版本号),这样可以确保事务读取的数据行,要么是事务开始前已经存在的,要么是当前事务插入或修改过的。
- 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读到到的行,在事务开始之前未删除。
INSERT操作:
为插入的每一行保存当前事务的系统版本号作为行版本号。
DELETE操作:
为删除的每一行保存当前事务的系统版本号作为行的删除标识。
UPDATE操作:
插入一条新纪录,保存当前事务版本号作为行版本号,同时保存当前事务版本号到原有行作为删除标识。
MVCC机制可以确保在大多数情况下的读操作都不需要加锁,使得读数据操作很简单、性能更好,并且能确保读取到符合标准的数据。不足之处是每行记录都需要额外的空间,并且要做更多的检查工作,以及一些额外的维护工作。
MVCC只在REPEATABLE READ和READ COMMITTED 两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容。
相关文章:
数据库事务隔离级别
前几天项目上合作公司的系统出现了一次死锁,突然想到由于近几年开发设计的系统并发用户比较少,很久没有碰到过死锁了,因此对死锁的概念也比较生疏了,需要温习一下。 事务 先从最基本的概念开始,事务、及其ACID特性。…...
Pytest 记录日志输出到控制台和写入文件
目录 自定义日志记录器和内置的日志记录器 项目代码 项目目录树 自定义日志记录器 函数源代码 pytest中定义和覆盖日志记录信息 使用cli定义Logging 使用pytest.ini定义Logging 修改单个测试级别的日志 日志输出的重要性不言而喻,不仅可以观测执行过程&…...
LINUX网络FTP服务
一、FTP服务 FTP服务:file transfer protocol :文件传输协议。在网络上进行双向传输,也是一个应用程序。不同的操作系统有不同的FTP软件,但使用的协议是一样的。 FTP协议基于TCP协议,有两个端口,即20和21。 20端口&…...
10 C++11
10 C11 1、类型推导1.1 auto关键字1.2 auto类型推断本质 2、类型计算2.1 类型计算分类2.2 类型计算的四种规则2.3 返回值类型计算 3、列表初始化4、Lambda表达式4.1 前置知识4.2 Lambda表达式4.3 捕获表 5、右值引用5.1 概念5.2 左值引用和右值引用 6、移动语义 1、类型推导 1…...
java的封装
为什么要封装?在java的面向对象的思想中,封装是指将类的实现细节包装,隐藏起来的方法。封装可以防止本类的代码和数据被外部定义的代码随机访问。 如何进行封装? 在定义一个类时,将类中的属性私有化,即使…...
为什么选择海外服务器?
如何选择跨境电商服务器:详细指南 选择合适的服务器是跨境电商企业成功的基础。服务器的性能和稳定性直接影响着网站的访问速度、用户体验和安全性,进而影响着企业的销量和利润。那么,跨境电商企业该如何选择服务器呢? 1. 确定目…...
k8s+springcloud+nacos部署配置
1 k8s 部署nacos-2.1.2配置k8s-nacos-statefulSet.yaml文件 apiVersion: v1 kind: Service metadata:name: nacos-headlessnamespace: rz-dtlabels:app: nacosannotations:service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec:# 3个端口打开&…...
梯度提升决策树(GBDT)
GBDT(Gradient Boosting Decision Tree),全名叫梯度提升决策树,是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学习器(树&am…...
数据结构之B树的原理与业务场景
B树是一种自平衡的树形数据结构,它能够保持数据有序,并且可以高效地进行查找、顺序访问、插入和删除操作。B树的设计是为了优化磁盘I/O操作,因为它可以减少磁盘访问次数,这在数据库和文件系统中非常有用。 1. B树的原理 节点的出…...
【Android面试八股文】你能说一说线程池管理线程的原理吗?
面试官(Interviewer): 欢迎参加面试,今天我们会讨论一些关于 Java 线程池管理的问题。你能给我解释一下 ThreadPoolExecutor 是如何管理线程的吗? 候选人(Candidate): 当然可以,ThreadPoolExecutor 是 Java 中用于创建和管理线程池的核心类。它通过一组核心参数来控制线…...
springer 在线投稿编译踩坑
springer投稿,在线编译踩坑总结 注意: 有的期刊需要双栏,而预定义的模板中可能为单栏,需要增加iicol选项。 例如: \documentclass[sn-mathphys-num]{sn-jnl}% —>\documentclass[sn-mathphys-num, iicol]{sn-jnl}…...
固态硬盘的指标
固态硬盘的指标主要包括以下几个方面: 接口类型:这是固态硬盘与外部设备连接的方式,常见的接口类型有SATA、PCIe和NVMe等。不同的接口类型决定了固态硬盘的传输速度和性能。例如,PCIe接口的固态硬盘通常比SATA接口的固态硬盘具有…...
mysql 分组后每个取最新的一条记录
在MySQL中,若要从一个分组中获取每组的最新一条记录(通常基于时间戳或其他递增的列),可以使用子查询或者窗口函数(如果MySQL版本支持)。 以下是两种不同的实现方法: 方法1: 使用子查询和LIMIT…...
Java语法和基本结构介绍
Java语法和基本结构是Java编程的基础,它决定了Java代码的书写方式和程序的结构。以下是Java语法和基本结构的一些关键点: 1.标识符和关键字:Java中的标识符是用来标识变量、函数、类或其他用户自定义元素的名称。关键字是预留的标识符&#x…...
TDengine 3.3.0.0 引入图形化管理工具、复合主键等 13 项关键更新
在涛思数据研发团队的努力下,TDengine 3.3.0.0 版本终于和大家见面了。这一版本中,我们引入了多项革新功能和性能优化,力求在为用户提供极致体验的同时,不断推动技术的前沿。 此次更新不仅针对开源社区版本,进行了一系…...
C++基础之红黑树
二叉搜索树 二叉搜索树(Binary Search Tree,BST)是一种二叉树,具有以下性质: 左子树节点值小于根节点值:对于树中的每个节点 x,其左子树中所有节点的值都小于 x 的值。右子树节点值大于根节点值…...
ClickHouse数据库对比、适用场景与入门指南
本文全面对比了ClickHouse与其他数据库(如StarRocks、HBase、MySQL、Hive、Elasticsearch等)的性能、功能、适用场景,并提供了ClickHouse的教学入门指南,旨在帮助读者选择合适的数据库产品并快速掌握ClickHouse的使用。 文章目录 …...
举例说明 如何通过SparkUI和日志定位任务莫名失败?
有一个Task OOM: 通过概览信息,发现Stage 10的Task 36失败了4次导致Job失败。概览信息中显示最后一次失败的退出代码(exit code)是143,意味着发生了内存溢出(OOM,即Out of Memory)。…...
Vue前端通过Axios的post方式传输数据,后端为什么一直接收的值是null?
沃靠!这个细节太细了,搞了我两个多小时才找到这个bug。 一、 首先官方文档给我的post请求的例子是这样的: axios.post(/user, {firstName: Fred,lastName: Flintstone}).then(function (response) {console.log(response);}).catch(function (error) {console.log(error);})…...
外链建设如何进行?
理解dofollow和nofollow链接,所谓dofollow链接,就是可以传递权重到你的网站的链接,这种链接对你的网站排名非常有帮助,这种链接可以推动你的网站在搜索结果中的位置向上爬,但一个网站全是这种有用的链接,反…...
OpCore Simplify:颠覆传统的黑苹果智能配置工具
OpCore Simplify:颠覆传统的黑苹果智能配置工具 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify OpCore Simplify是一款专为简化OpenCore E…...
提升五倍效率:基于快马平台优化openclaw数据采集工作流
最近在做一个数据采集项目时,发现传统的手动编写爬虫脚本效率实在太低了。每次遇到反爬机制或者需要调整采集策略时,都要花大量时间修改代码。后来尝试用openclaw结合InsCode(快马)平台来优化工作流,效率直接提升了五倍多,这里分享…...
Illustrator自动化革命:25个免费脚本如何将设计效率提升300%
Illustrator自动化革命:25个免费脚本如何将设计效率提升300% 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为Illustrator中重复繁琐的操作而烦恼吗?每…...
OpenClaw跨平台控制:千问3.5-35B-A3B-FP8任务手机端触发与查看
OpenClaw跨平台控制:千问3.5-35B-A3B-FP8任务手机端触发与查看 1. 为什么需要移动端控制OpenClaw? 上周五晚上十点半,我正躺在沙发上刷手机,突然想起有个重要的数据报表还没生成。如果按传统方式,我得爬起来开电脑、…...
插件管理系统的核心实践:从依赖解析到冲突检测的全流程优化
插件管理系统的核心实践:从依赖解析到冲突检测的全流程优化 【免费下载链接】skyrimse The TES V: Skyrim Special Edition masterlist. 项目地址: https://gitcode.com/gh_mirrors/sk/skyrimse 在现代软件架构中,插件管理系统扮演着至关重要的角…...
暗黑3按键助手:5分钟掌握解放双手的游戏自动化神器
暗黑3按键助手:5分钟掌握解放双手的游戏自动化神器 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper 还在为暗黑破坏神3中重复的技能按键和…...
Qt信号槽机制:安全实现子线程与主线程界面交互
1. 为什么子线程不能直接操作主线程界面? 这个问题困扰过很多Qt开发者。我刚开始用Qt做多线程开发时,也遇到过界面莫名其妙崩溃的情况。最让人头疼的是,这种崩溃往往是偶发性的,可能测试十次才出现一次,但用户用着用着…...
抖音音频批量提取:5分钟学会免费下载抖音原声和视频
抖音音频批量提取:5分钟学会免费下载抖音原声和视频 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…...
Display Driver Uninstaller(DDU)深度技术指南:从根源清除到系统优化
Display Driver Uninstaller(DDU)深度技术指南:从根源清除到系统优化 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-driver…...
NBTExplorer终极指南:如何轻松可视化编辑Minecraft NBT数据
NBTExplorer终极指南:如何轻松可视化编辑Minecraft NBT数据 【免费下载链接】NBTExplorer A graphical NBT editor for all Minecraft NBT data sources 项目地址: https://gitcode.com/gh_mirrors/nb/NBTExplorer NBTExplorer是一款专为Minecraft玩家和开发…...
