MySQL事务与锁机制详细讲解

事务与锁机制是数据库系统中非常重要的概念,尤其在 MySQL 这样的关系型数据库中,它们决定了数据的 一致性完整性并发控制。下面我将详细讲解事务和锁机制,分步骤深入分析。


一、事务(Transaction)

1. 什么是事务?

事务是一组操作的集合,这些操作要么全部执行成功,要么全部失败回滚,保证数据库的 一致性完整性

2. 事务的四大特性(ACID)

  • A - 原子性(Atomicity)
    事务中的所有操作是一个不可分割的整体,要么全部执行,要么全部不执行。

    例子:银行转账,A账户转100元给B账户,要么两步都完成(A扣款,B加款),要么都不完成(回滚)。

  • C - 一致性(Consistency)
    事务开始前和结束后,数据库保持一致的状态。

    例子:无论事务成功与否,两个账户的总金额保持不变。

  • I - 隔离性(Isolation)
    并发执行的事务互不影响,每个事务的操作在完成前对其他事务是不可见的。

    例子:当两个事务同时更新同一条数据时,事务 A 的操作不会影响事务 B,反之亦然。

  • D - 持久性(Durability)
    一旦事务提交,数据会永久保存,即使系统崩溃也不会丢失。

    例子:事务提交后,数据写入磁盘,保证数据不丢失。


3. MySQL 事务的实现

MySQL 支持事务的存储引擎是 InnoDB。其他存储引擎(如 MyISAM)不支持事务。

事务的基本语法
 

sql

-- 开始事务 START TRANSACTION; -- SQL 操作 UPDATE account SET balance = balance - 100 WHERE name = 'A'; UPDATE account SET balance = balance + 100 WHERE name = 'B'; -- 提交事务 COMMIT; -- 回滚事务 ROLLBACK;

事务的两种结束方式
  1. 提交(COMMIT):事务中的所有操作成功完成,并永久保存。
  2. 回滚(ROLLBACK):撤销事务中的所有操作,数据库回到事务开始时的状态。
自动提交模式
  • 在 MySQL 中,默认开启 自动提交模式。每执行一条 SQL 语句,MySQL 会自动提交。
  • 关闭自动提交:
     

    sql

    复制代码

    SET autocommit = 0;


二、事务的隔离级别

1. 为什么需要隔离级别?

在并发环境下,多个事务同时操作数据库,会引发 并发问题,如脏读、不可重复读和幻读。

2. 并发问题

  • 脏读(Dirty Read)
    一个事务读到了另一个未提交事务修改的数据。
  • 不可重复读(Non-Repeatable Read)
    在同一事务中,前后两次查询的数据不一致,因为其他事务修改了数据。
  • 幻读(Phantom Read)
    在同一事务中,前后两次查询结果的行数不一致,因为其他事务插入/删除了数据。

3. MySQL 的四种隔离级别

MySQL 支持 四种事务隔离级别,从低到高依次是:

隔离级别脏读不可重复读幻读特点
Read Uncommitted允许允许允许最低级别,读到未提交数据
Read Committed禁止允许允许只读取已提交数据(Oracle默认)
Repeatable Read禁止禁止允许可重复读(MySQL 默认级别)
Serializable禁止禁止禁止最高级别,完全串行化操作
设置事务隔离级别
 

sql

复制代码

-- 查看当前隔离级别 SELECT @@TRANSACTION_ISOLATION; -- 设置隔离级别为 Repeatable Read SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;


三、锁机制

1. 为什么需要锁?

在并发操作中,多个事务可能对同一资源进行读写操作,为了防止数据不一致或损坏,MySQL 采用锁机制来控制并发访问。

2. MySQL 锁的分类

MySQL 的锁主要分为以下几类:

1)按照锁的粒度分类
  • 表锁(Table Lock)

    • 锁定整个数据表。
    • 粒度大,开销小,适用于读多写少的场景。
    • MyISAM 存储引擎使用表锁。
  • 行锁(Row Lock)

    • 锁定某一行记录。
    • 粒度小,开销大,适用于高并发场景。
    • InnoDB 支持行锁。
2)按照锁的类型分类
  • 共享锁(S锁)
    允许多个事务同时读数据,互不影响。

     

    sql

    复制代码

    SELECT * FROM table_name LOCK IN SHARE MODE;

  • 排他锁(X锁)
    排他性地锁定数据,其他事务无法读写被锁定的数据。

     

    sql

    复制代码

    SELECT * FROM table_name FOR UPDATE;

3)间隙锁(Gap Lock)
  • 间隙锁 用于防止幻读,锁定一个范围内的数据,甚至包括不存在的数据。
  • 发生在 Repeatable Read 隔离级别 下。

3. 锁的实现方式

在 InnoDB 中,锁是通过 索引 实现的。如果查询未使用索引,InnoDB 会退化为表锁。

行锁与索引
 

sql

复制代码

-- 通过主键索引加行锁 SELECT * FROM table_name WHERE id = 1 FOR UPDATE; -- 未使用索引,退化为表锁 SELECT * FROM table_name WHERE name = '西瓜' FOR UPDATE;


四、事务与锁的结合使用

在实际开发中,事务和锁通常结合使用。例如:

 

sql

复制代码

START TRANSACTION; -- 通过行锁确保事务的隔离性 SELECT * FROM account WHERE name = 'A' FOR UPDATE; UPDATE account SET balance = balance - 100 WHERE name = 'A'; SELECT * FROM account WHERE name = 'B' FOR UPDATE; UPDATE account SET balance = balance + 100 WHERE name = 'B'; COMMIT;

  • 使用 FOR UPDATE 加排他锁,确保数据安全。
  • 在高并发下避免 死锁锁等待

总结

  1. 事务 通过 ACID 保证数据一致性。
  2. 隔离级别 决定事务之间的并发控制程度。
  3. 锁机制 控制并发访问,InnoDB 支持行锁、表锁和间隙锁。
  4. 结合事务和锁,可以实现高并发下的数据安全操作。

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

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

相关文章

LWIP协议:三次握手和四次挥手、TCP/IP模型

一、三次握手:是客户端与服务器建立连接的方式; 1、客户端发送建立TCP连接的请求。seq序列号是由发送端随机生成的,SYN字段置为1表示需要建立TCP连接。(SYN1,seqx,x为随机生成数值);…

使用winscp从windows访问Ubuntu进行文件传输

Ubuntu 系统上的准备工作 • 安装 SSH 服务器: 确保 Ubuntu 系统上已经安装了 SSH 服务器。如果没有安装,可以使用以下命令安装: sudo apt update sudo apt install openssh-server • 启动 SSH 服务: 确保 SSH 服务正在运行&a…

Springboot中使用Retrofit

Retrofit官网 https://square.github.io/retrofit/ 配置gradle implementation("com.squareup.okhttp3:okhttp:4.12.0")implementation ("com.squareup.retrofit2:retrofit:2.11.0")implementation ("com.squareup.retrofit2:converter-gson:2.11.0…

[机器学习]AdaBoost(数学原理 + 例子解释 + 代码实战)

AdaBoost AdaBoost(Adaptive Boosting)是一种Boosting算法,它通过迭代地训练弱分类器并将它们组合成一个强分类器来提高分类性能。 AdaBoost算法的特点是它能够自适应地调整样本的权重,使那些被错误分类的样本在后续的训练中得到…

PHP代码审计学习(一)--命令注入

1、漏洞原理 参数用户可控&#xff0c;程序将用户可控的恶意参数通过php可执行命令的函数中运行导致。 2、示例代码 <?php echorec-test; $command ping -c 1 .$_GET[ip]; system($command); //system函数特性 执行结果会自动打印 ?> 通过示例代码可知通过system函…

【并发容器】源码级ConcurrentHashMap详解(java78)

1. ConcurrentHashMap 为什么要使用ConcurrentHashmap 在多线程的情况下&#xff0c;使用HashMap是线程不安全的。另外可以使用Hashtable&#xff0c;其是线程安全的&#xff0c;但是Hashtable的运行效率很低&#xff0c;之所以效率低下主要是因为其实现使用了synchronized关…

Redis的基本使用命令(GET,SET,KEYS,EXISTS,DEL,EXPIRE,TTL,TYPE)

目录 SET GET KEYS EXISTS DEL EXPIRE TTL redis中的过期策略是怎么实现的&#xff08;面试&#xff09; 上文介绍reids的安装以及基本概念&#xff0c;本章节主要介绍 Redis的基本使用命令的使用 Redis 是一个基于键值对&#xff08;KEY - VALUE&#xff09;存储的…

基于SpringBoot的乡村信息服务平台的设计与实现

摘 要 乡村信息服务平台的研究背景源于当前乡村振兴战略的实施和信息化技术的快速发展。随着城乡经济差距的逐渐凸显&#xff0c;乡村信息服务平台成为一种新型的信息化手段。本系统采用Java语言&#xff0c;MySQL数据库&#xff0c;采用MVC框架, JS技术开发。乡村信息服务平…

大数据技术与应用——数据可视化(山东省大数据职称考试)

大数据分析应用-初级 第一部分 基础知识 一、大数据法律法规、政策文件、相关标准 二、计算机基础知识 三、信息化基础知识 四、密码学 五、大数据安全 六、数据库系统 七、数据仓库. 第二部分 专业知识 一、大数据技术与应用 二、大数据分析模型 三、数据科学 数据可视化 大…

sql中case when若条件重复 执行的顺序

sql case when若条件重复 执行的顺序 在 SQL 中&#xff0c;如果你在 CASE 表达式中定义了多个 WHEN 子句&#xff0c;并且这些条件有重叠&#xff0c;那么 CASE 表达式的执行顺序遵循以下规则&#xff1a; &#xff08;1&#xff09;从上到下&#xff1a;SQL 引擎会按照 CASE …

【并发容器】ConcurrentLinkedQueue:优雅地实现非阻塞式线程安全队列

实现一个线程安全的队列有两 种方式:一种是使用阻塞算法&#xff0c;另一种是使用非阻塞算法。使用阻塞算法的队列可以用一个锁 (入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现。非阻塞的实现方 式则可以使用循环CAS的方式来实现。 1. 简介 ConcurrentLi…

Flink CDC 读取oracle库数据性能优化

通过综合考虑Oracle数据库配置、Flink作业配置以及其他优化措施&#xff0c;可以显著提升Flink CDC读取Oracle库数据的性能和效率。可以从以下几个方面进行&#xff1a; 一、Oracle数据库配置优化 ‌开启归档日志‌&#xff1a; 通过执行sqlplus /assysdba或sqlplus/nolog命令…

SpringAop-拦截参数带注解的方法

拦截方法中参数类型为String 且带有Crypto注解的方法&#xff1a;execution(* *(..,Crypto (String),..)) 拦截方法中参数上带有Crypto注解的方法&#xff1a;execution(* *(..,Crypto (*),..)) ..&#xff1a;零个或者多个 *&#xff1a;通配符 样例 /*** 针对带有Crypto…

selenium获取请求头

【原创】Selenium获取请求头、响应头-腾讯云开发者社区-腾讯云 selenium 4.0.0 selenium-wire 5.1.0 python 3.10 from seleniumwire import webdriver import time from selenium.webdriver.common.by import By import re def get_request_headers(driver):"""…

【C++移动语义与完美转发】左值右值,引用,引用折叠,移动语义,万能引用与完美转发

前言 nav2系列教材&#xff0c;yolov11部署,系统迁移教程我会放到年后一起更新&#xff0c;最近年末手头事情多&#xff0c;还请大家多多谅解。本期是一个鸽了半年的教程&#xff0c;很早以前我就一直想写一篇文章有关C的移动语义&#xff0c;一直拖到现在()&#xff0c;那么今…

暂停一下,给Next.js项目配置一下ESLint(Next+tailwind项目)

前提 之前开自己的GitHub项目&#xff0c;想着不是团队项目&#xff0c;偷懒没有配置eslint&#xff0c;后面发现还是不行。eslint的存在可以帮助我们规范代码格式&#xff0c;同时 ctrl s保存立即调整代码格式是真的很爽。 除此之外&#xff0c;团队使用eslint也是好处颇多…

iOS 应用的生命周期

Managing your app’s life cycle | Apple Developer Documentation Performance and metrics | Apple Developer Documentation iOS 应用的生命周期状态是理解应用如何在不同状态下运行和管理资源的基础。在 iOS 开发中&#xff0c;应用生命周期管理的是应用从启动到终止的整…

Hadoop学习笔记(包括hadoop3.4.0集群安装)(黑马)

Hadoop学习笔记 0-前置章节-环境准备 0.1 环境介绍 配置环境&#xff1a;hadoop-3.4.0&#xff0c;jdk-8u171-linux-x64 0.2 VMware准备Linux虚拟机 0.2.1主机名、IP、SSH免密登录 1.配置固定IP地址&#xff08;root权限&#xff09; 开启master&#xff0c;修改主机名为…

扩展SpringBoot中的SpringMVC的默认配置

SpringBoot默认已经给我们做了很多SpringMVC的配置&#xff0c;哪些配置&#xff1f; 视图解析器ViewResolver静态资料的目录默认首页index.html图标名字和图标所在目录&#xff0c;favicon.ico类型转换器Converter&#xff0c;格式转换器的Formatter消息转换器HttpMessageCon…

企业内训|阅读行业产品运营实战训练营-某运营商数字娱乐公司

近日&#xff0c;TsingtaoAI公司为某运营商旗下数字娱乐公司组织的“阅读行业产品运营实战训练营”在杭州落下帷幕。此次训练营由TsingtaoAI资深互联网产品专家程靖主持。该公司的业务骨干——来自内容、市场、业务、产品与技术等跨部门核心岗位、拥有8-10年实战经验的中坚力量…