mysql的事务和锁

MySQL事务和锁 作者:IT王小二 博客:https://itwxe.com MySQL是怎么解决并发事务所产生的问题呢?又借助了哪些锁的思想呢?这篇小二给小伙伴们继续唠一唠MySQL的那些事。 一、事务是什么 事务是由一组SQL语句组成的逻辑处理单元,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。通常有下面4个特性,也就是咱程序猿俗称的ACID属性。 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全部执行,要么全部不执行。举个例子:情人节小二给女朋友转账520块,那么SQ. 阅读详情

1 事务的ACID特性

mysql引入事务的目的是为了保证数据操作的一致性,有了事务之后,用户可以把一组操作定义为原子性的操作。mysql的事务具有ACID的特性。

  • 原子性(atomicity):一个事务定义了一组操作,其实mysql执行的不可分割的最小工作单位。事务中的操作要么全部成功,要么全部失败,不会出现只有部分成功的情况。
  • 一致性(consistency):一致性定义了mysql数据状态只能从一个一致性状态到另外一个一致性状态,其保证用户不会读取到原子操作中的部分中间结果。
  • 持久性(durability):持久性是指事务提交后,其修改不会因为系统的稳定性而丢失,如mysql系统崩溃、服务器断电等。
  • 隔离性(isolation):其表明的是事务与事务之间的可见性,其中事务被定义了四种隔离级别,未提交读、提交读、可重复读、串行化。其中mysql默认隔离级别可重复读,其保证事务中的读取操作在任何时间段读取的结果都是一样的,并且不会受其他事务的影响(提交或者未提交)。

    在我们具体介绍事务的这四个特性之前还需要介绍下mysql中锁的概念。其中锁在是否加锁的上分为乐观锁和悲观锁,其中乐观锁是一种通过多版本控制的方式来实现类似加锁的操作,其本质上是每次对数据的更新都会改变数据的版本,并且在回写的时候回检查当前版本是不是修改之前的版本,如果不是证明已经有其他程序更改过该数据,这样的回写操作会失败。如此来保证了数据的一致性。其中mvcc就是mysql的乐观锁实现。悲观锁则是需要在数据上进行加锁从而来保证数据的一致性,其中有根据锁的并发粒度分为共享锁(读锁)和互斥锁(写锁)。共享锁是指所有的读操作都能共享的使用同一锁从而提高读锁的并发度。互斥锁是指所有的所有加了互斥锁的数据,不能能够再加读锁和写锁,使得需要加锁的读和写操作都要等待该互斥锁的释放。在mysql中是通过悲观锁来解决幻读的问题。

1.1 事务的原子性实现(undo log)

mysql实现原子性操作是同对每个一个事务的操作都记录一个undo log,当事务执行失败时,通过undo log来回滚到事务的初始状态。同时由于事务的隔离性保证了这样的回滚操作不会影响其他的事务,因为其他事务还是读取该事务开始时的数据。对于写操作会加互斥锁,因此通过undo log回滚到事务的开始状态也不会出现数据覆盖导致变更丢失的危险。

Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log)。然后进行数据的修改。如果出现了错误或者用户执行ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。

用Undo Log实现原子性和持久化的事务的简化过程:假设有A、B两个数据,值分别为1,2。

  1. 事务开始,记录A=1到undo log.
  2. 修改A=3.
  3. 记录B=2到undo log.
  4. 修改B=4.
  5. 将undo log写到磁盘。
  6. 将数据写到磁盘。
  7. 事务提交

这里有一个隐含的前提条件:‘数据都是先读到内存中,然后修改内存中的数据,最后将数据写回磁盘’。之所以能同时保证原子性和持久化,是因为以下特点:

  • 更新数据前记录Undo log。
  • 为了保证持久性,必须将数据在事务提交前写到磁盘。只要事务成功提交,数据必然已经持久化。
  • Undo log必须先于数据持久化到磁盘。如果在6,7之间系统崩溃,undo log是完整的,可以用来回滚事务。
  • 如果在1-6之间系统崩溃,因为数据没有持久化到磁盘。所以磁盘上的数据还是保持在事务开始前的状态。

1.2 事务的持久性实现(redo log)

其实如果按照上述undo的方式进行实现那么数据的持久性已经得到保证了,但是其有一个很大的缺点:每个事务提交前将数据和Undo Log写入磁盘,这样会导致大量的磁盘IO,因此性能很低。并且根据2-8原理该写入的数据很快的会重新被读取出来,如果需要每次把变更的数据写入硬盘之后,再进行读取,不仅吞吐量低,并且磁盘IO会成倍数增加。因此如果能够将数据缓存一段时间,就能减少IO提高性能。但是这样就会丧失事务的持久性,事务提交了但是数据并没有写入磁盘,如果系统崩溃就会操作数据的丢失。因此引入了另外一种机制来实现持久化,即Redo Log.
和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。
Undo + Redo事务的简化过程:假设有A、B两个数据,值分别为1,2.

  1. 事务开始.记录A=1到undo log.
  2. 修改A=3.
  3. 记录A=3到redo log.
  4. 记录B=2到undo log.
  5. 修改B=4.
  6. 记录B=4到redo log.
  7. 将undo log 和 redo log写入磁盘。
  8. 事务提交

Undo + Redo事务的特点

  • 为了保证持久性,必须在事务提交前将Redo Log持久化。
  • 数据不需要在事务提交前写入磁盘,而是缓存在内存中。
  • Redo Log 保证事务的持久性。
  • Undo Log 保证事务的原子性。
  • 有一个隐含的特点,数据必须要晚于redo log写入持久存储。

数据恢复策略:

  • 已经提交的事务通过redo log进行恢复。
  • 未提交的事务通过undo log 进行回滚。

1.3 事务的隔离性

mysql的默认隔离级别为可重复读,其实现方式是MVCC(多版本控制)。mvcc的主要作用是保证同一个事务的多次的同一个读操作前后两次读的结果是一致的,其原理是在事务中第一次读取时会记录数据库中记录的版本,即使另外一个事务对数据进行更改并已提交,在后续读取时依然是以前版本的数据,不是最新版本,其类似于快照数据,因此对于事务中的读取操作都是快照读,并且事务之间的中间结果是互相不可见的。注意:没有事务的读取操作是读取的最新版本的数据,没有隔离性。对于在事务中(select * from xxx lock in share mode 或者 select * from xxx for update)会申请加锁,因此对于后续需要修改的操作都会被阻塞。因此对于需要加锁的操作读取的都是最新的数据,又叫当前读(当前版本对应于快照读)。多版本控制就是指在数据库中同时存在多个版本的数据,正式由于多版本控制保证了mysql的事务隔离级别为可重复读。

1.4 事务的一致性

由于事务的原子性和隔离性保证了数据只会从一个一致性状态变到另外一个一致性。因此原子性保证一个事务的一组操作只会同时成功或者同时失败,再加上数据的隔离性保证了事务间的一组操作的中间结果是不可见的。从而最终保证了数据的一致性。

2 加锁解决幻读

什么是幻读:http://blog.youkuaiyun.com/cweeyii/article/details/70991230
何登成mysql博客:http://hedengcheng.com/?p=771
在mysql事务中根据是否加锁可以分为两类操作:

  1. 快照读,简单的select操作,属于快照读,不加锁。 select * from table where ?;
  2. 当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。select * from table where ? lock in share mode;select * from table where ? for update; insert into table values (…); update table set ? where ?; delete from table where ?;
    所有以上的语句,都属于当前读,读取记录的最新版本。并且,读取之后,还需要保证其他并发事务不能修改当前记录,对读取记录加锁。其中,除了第一条语句,对读取记录加S锁 (共享锁)外,其他的操作,都加的是X锁 (排它锁)。
    对于快照读和当前读都是在第一次读取时进行版本控制或者加锁,和事务的开始时间没有关系。
海思Hi3516平台集成IMX214 Sensor实战:从I2C调试到VI通路构建 本文详细记录了在海思Hi3516平台上集成索尼IMX214图像传感器的完整实战过程。从硬件I2C通讯调试、驱动层适配,到上层VI通路构建与ISP配置,提供了系统性的排查步骤与代码修改要点,旨在帮助开发者快速打通从Sensor到屏幕的完整视频采集链路,解决集成过程中的常见问题。 阅读详情

相关推荐

常规波束形成——时域波束形成、频域波束形成

本文介绍了波束成形,包括时域波束成形和频域波束成形,并解释了在实现过程可能存在疑惑的相位补偿。

Candy_Editor的博客 3660

MySql的事务和锁详解

数据库事务详细说明,事务实现原理,锁类型,锁的使用,MVCC多版本控制,分布式事务概要说明等

m0_37685866的博客 2018

keil软件调试(Debug)仿真教程(软件调试和硬件调试的区别)及常用调试按键详解

单片机的调试分为两种,一种是使用软件模拟调试,第二种是硬件调试,两种调试方式各有不同,软件模拟调试有误差,而硬件调试,借用仿真器调试是嵌入式开发中常用方法。

weixin_51624736的博客 3万+

MySQL 事务和锁

事务是把一组SQL语句打包成为一个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。如果不用事务管理,当执行第一条SQL语句之后,服务器崩溃了那么整体的数据就不正确了。

2401_85234841的博客 1139

波分复用-Zblock仿真

Z-BLOCK是一种用于光通信模块的光学元件,其核心结构是在玻璃块一侧贴有4个特定波长滤光片,另一侧镀有反射膜和增透膜。光信号在内部呈现Z字形反射路径,实现波长分离。文章以可见光LED为例,在ZEMAX中演示了非序列模式下的建模过程,重点介绍了滤光片和膜层的参数设置方法。需要注意的是,入射角度需根据玻璃折射率、通道高度和厚度精确计算,否则可能导致光泄漏。该建模方法同样适用于光通信中的光纤激光器系统。

Zhaxibamao的博客 1748

深入解析时钟同步技术:相位同步、频率同步与同源时钟的实战应用

本文深入解析时钟同步技术的三种核心方式:相位同步、频率同步与同源时钟,详细阐述其技术原理、实现方案及实战应用。通过对比分析不同同步方式的特点与适用场景,为电子系统设计提供选型指南,帮助工程师优化时钟网络设计,提升系统稳定性和性能。

weixin_29240711的博客 449

【数据库】详解MySQL数据库中的事务与锁

锁定粒度:表锁>行锁加锁效率:表锁>行锁冲突概率:表锁>行锁并发性能:表锁<行锁。

2302_78914800的博客 1444

【亲测有效】OpenClaw Gateway 出现 “(no output)“ 卡死问题完整解决指南:从手动重启到 systemd Watchdog 自动恢复

最近在使用 OpenClaw(自托管 AI 助手框架,前身 Clawdbot/Moltbot)时,遇到了一个非常常见的顽疾:TUI(终端界面)或 Telegram 等通道经常显示 "(no output)",消息发出去后机器人完全没反应,看起来像是卡死了。

hampeter的博客 8609

【MySQL】MySQL 事务和锁详解

MySQL事务是保证数据库操作一致性的核心机制,具有ACID特性(原子性、一致性、隔离性、持久性)。事务通过BEGIN开启,COMMIT提交或ROLLBACK回滚,确保操作要么全部成功,要么全部失败。原子性通过undolog实现回滚;一致性要求数据始终满足约束;隔离性通过MVCC和锁机制控制并发访问,解决脏读、不可重复读等问题,支持4种隔离级别(读未提交、读已提交、可重复读、串行化)。实际应用如转账场景中,必须保证扣款和入账操作的原子性,避免数据不一致。

Antonio915的博客 1492

A*寻路算法的最简单通俗讲解

为什么我的眼里常含泪水?因为我有一个算法不会。为了节约点眼泪,今天我们就来介绍著名的A*寻路算法(或简称A*算法)。 Peter Hart, Nils Nilsson 和 Bertram Raphael 在1968年首次提出了著名的A*算法。A*算法其实是Dijkstra最短路径算法的一种扩展。不一样的是,在A*算法中我们需要使用Heuristics 来导引搜索过程,以期达到更好的表现。 ...

白马负金羁 2万+

基于 YOLO26 的车辆实时检测与计数系统

本文提出了一种基于YOLO26的车辆实时检测与计数系统。系统采用CSPDarknet53作为主干网络,结合特征金字塔和多尺度预测实现高精度车辆检测。通过DeepSORT算法进行目标跟踪,并统计车辆数量、行驶方向和交通流量。实验表明,该系统在保持实时性能的同时,检测精度达到92.3%,可有效应用于智能交通管理。系统采用Python实现,支持GPU加速,适用于多种交通场景下的车辆监测需求。

一键难忘的博客 908

【MySQL】剖析事务和锁

使用事务而不是使用 LOCK TABLES 语句手动加锁,并使用 innodb_lock_wait_timeout 变量设置锁的超时时间,保证任何情况下锁都可以自动释放。 经常使用 SHOW ENGINE INNODB STATUS 命令来确定最近一次死锁的原因。这可以帮助我们修改应用程序以避免死锁。 如果出现频繁的死锁警告,可以通过启用 innodb_print_all_deadlocks 变量来收集调试信息。对于死锁的信息,都记录在 MySQL 错误日志中,调试完成后记得禁用此选项。 如果事务由于死锁而

2302_79806056的博客 1116

基于 Qt C++ 开发一套西门子量子测量系统的控制与数据采集平台

sensorIdCombo->addItems({"QTS-100-001 (温度)", "QPG-200-001 (压力)", "QDS-300-001 (位移)"});precisionTable->setHorizontalHeaderLabels({"传感器ID", "类型", "标称精度", "实际精度", "校准状态"});QWidget *dispWidget = createSensorWidget("量子位移", "mm (±1μm)", 50.0, 0.001);// 传感器状态更新。

寒寒豆豆软件公司的博客 254

MySql 事务 & 锁

一组逻辑操作单元,使数据从一种状态变换到另一种状态。保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。

cimbala的博客 830

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

MySQL的事务以及锁详解

老铁有一提问“MySQL的可重复读级别能解决幻读吗”,一听就有猫腻,实话说,之前从未思考到这个问题,很是懵逼,于是深入查看,发现了自己的细节欠缺是在太多,补上! 事务基础知识: 数据库原理理论 事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。在关系数据库中,一个事务可以是一组SQL语句或整个程序。

qq_22162093的博客 2723

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

mysql中的锁和事务

本文系统介绍了MySQL中的事务与锁机制。首先阐述了事务的ACID特性(原子性、一致性、隔离性、持久性)及其隔离级别(Read Uncommitted、Read Committed、Repeatable Read、Serializable),分析了不同隔离级别下可能出现的脏读、不可重复读和幻读问题。然后详细讲解了MySQL的锁机制,包括全局锁、表级锁(表锁、元数据锁、意向锁)和行级锁(记录锁、间隙锁、临键锁),重点说明了各种锁的适用场景、加锁方式及兼容性关系。文章最后特别指出InnoDB在Repeatabl

m0_71857053的博客 906

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

MySQL -事务、锁

MySQL事务以及锁

weixin_64612849的博客 1091

MySQL事务和锁总结

- 原子性(Atomicity) :一个事务中的操作,要么全部成功,要么全部失败,可以通过undo log回滚。 - 一致性(Consistent) :在事务的前后,数据都必须保持一致状态。如果事务在执行过程中被中断,导致一部分更新已经入库,但是这部分数据没有回滚,就出现了数据不一致。可以简单理解为和原子性类似,只是原子性关注的是行为,而一致性关注的是数据。

黄智霖的博客 2873

MySQL-事务与锁

本文将总结关于事务、事务隔离级别和数据库中的锁相关内容。

qq_74092815的博客 1011

Mysql事务和锁

事务就是把一组sql打包成一个整体,在sql执行中,要么都执行成功要么都执行失败。

huapiaoy的博客 1458

【MySQL】事务、锁

MySQL数据库事务和锁

低调做人,低调编码,神码都是浮云 1753

MySQL事务与锁

MySQL事务与锁是紧密相连的整体,需要互相配合使用,本文介绍了事务的隔离级别、共享锁、独占锁、间隙锁、记录锁、next-key锁,索引与锁的关系、以及MySQL默认隔离级别选择可重复读的原因、纠正多数博客对“幻读”的错误理解。

weixin_44922510的博客 894

mysql查看锁和事务

数据库事务和锁 INNODB_LOCKS, INNODB_LOCK_WAITS, INNODB_TRX表的简单介绍

秃头的博客 3378

2-MySQL的事务和锁

一、数据库为什么需要锁? 锁是实现事务的前提,数据库提供事务功能时,就是依赖锁实现的。即使不提供事务能力,也需要锁,例如MySQL的MyIsAM引擎是有表锁的。 如果没有锁,那么读、写可能同时发生,那么就会读取到还没有修改完的记录,比如一个业务逻辑是修改2个字段,刚修改了第一个字段,就被读取出去了,那么此时读取的数据是个未完全修改的数据,后果无法预知,又或者对一个字段的多个修改一起进行,最终修改结果是混合修改的等等,这些对于数据库系统来说,是致命的缺陷,所以锁是必须的,有些操作必须要不被打扰。 对于数据库

诗人不写诗 570
上一篇: mysql可重复读和幻读实例
下一篇: elasticsearch集群安装
CWeeYii
博客等级 码龄12年 26粉丝 42原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值