MySQL 数据库事务实践

引言

在现代应用程序开发中,确保数据库操作的完整性和一致性至关重要。MySQL 提供了强大的事务管理功能,允许开发者以原子性、一致性、隔离性和持久性(ACID)的方式处理数据。本文将通过详细的解释和实际示例,带你深入了解 MySQL 事务的工作原理,并展示如何在实际项目中应用这些知识。

目录

什么是事务

事务的 ACID 特性

MySQL 中的锁机制

事务隔离级别

事务控制语句

实战演练

环境准备

开始事务

执行多个 SQL 语句

查看当前状态

提交事务

测试回滚

使用保存点

常见问题及解决方案

总结

参考文献


什么是事务

事务 是一系列作为一个整体执行的操作序列,要么全部成功,要么完全不执行。它提供了对数据库操作的一种可靠方式,确保数据的一致性和完整性。例如,在银行转账过程中,扣款和存款必须同时成功或失败,否则会导致资金丢失或重复。


事务的 ACID 特性
  • 原子性(Atomicity):事务是一个不可分割的工作单位,所有操作要么全部完成,要么一个也不做。
  • 一致性(Consistency):事务必须使数据库从一个一致状态转变到另一个一致状态,即使在发生故障的情况下也应如此。
  • 隔离性(Isolation):并发执行的多个事务不会互相干扰,每个事务都像是独立运行一样。
  • 持久性(Durability):一旦事务提交,其对数据库的更改将是永久性的,即使系统崩溃也不会丢失。

MySQL 中的锁机制

MySQL 使用多种类型的锁来保证并发操作的安全性和效率:

  • 表级锁:锁定整个表,适用于 MyISAM 和 MEMORY 存储引擎。
  • 行级锁:只锁定需要操作的行,适用于 InnoDB 存储引擎。
  • 页面锁:锁定一个页面(通常包含多行),介于表锁和行锁之间。
  • 意向锁:用于解决表级锁与行级锁之间的冲突。
  • 共享锁:允许多个事务读取同一行数据,但不允许修改。
  • 排他锁:允许事务更新或删除一行数据,但禁止其他任何事务对该行加任何类型的锁。
  • 间隙锁:锁定索引记录之间的“间隙”,防止幻读现象。
  • Next-Key 锁:结合了行锁和间隙锁的功能,有效地防止幻读。
  • 自增锁:用于控制 AUTO_INCREMENT 列值的分配。

事务隔离级别

MySQL 支持四种标准的事务隔离级别,每种级别决定了不同事务之间相互可见的程度:

  1. 读未提交(READ UNCOMMITTED):最低的隔离级别,允许脏读。
  2. 读已提交(READ COMMITTED):不允许脏读,但允许不可重复读。
  3. 可重复读(REPEATABLE READ):这是 InnoDB 的默认隔离级别,保证同一事务内的多次读取结果相同,防止不可重复读。
  4. 串行化(SERIALIZABLE):最高的隔离级别,完全禁止了幻读现象,但性能开销较大。

设置隔离级别的语法如下:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

事务控制语句
  • 开始事务START TRANSACTION 或 BEGIN
  • 提交事务COMMIT
  • 回滚事务ROLLBACK
  • 保存点SAVEPOINT <identifier>
  • 释放保存点RELEASE SAVEPOINT <identifier>
  • 回滚到保存点ROLLBACK TO SAVEPOINT <identifier>

实战演练
环境准备

首先,创建一个测试数据库和表,并插入一些初始数据:

CREATE DATABASE IF NOT EXISTS test_db;
USE test_db;CREATE TABLE IF NOT EXISTS accounts (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(50),balance DECIMAL(10,2)
) ENGINE=InnoDB;INSERT INTO accounts (name, balance) VALUES ('Alice', 1000.00), ('Bob', 2000.00);
开始事务

使用 START TRANSACTIONBEGIN 来显式地开始一个事务:

START TRANSACTION;
执行多个 SQL 语句

在这个事务中,我们可以执行多个 SQL 语句,比如模拟转账操作:

-- 转账:从 Alice 的账户转 500 给 Bob
UPDATE accounts SET balance = balance - 500 WHERE name = 'Alice';
UPDATE accounts SET balance = balance + 500 WHERE name = 'Bob';
查看当前状态

可以在此时查询数据,查看当前事务中的更改是否生效:

SELECT * FROM accounts;

请注意,在事务未提交之前,这些更改只对当前事务可见,其他会话看不到这些更改。

提交事务

如果你对事务中的所有操作都满意,并希望将这些更改永久保存到数据库中,那么你可以提交事务:

COMMIT;
测试回滚

为了演示回滚的效果,我们可以再次开始一个新事务并故意制造一个错误:

START TRANSACTION;-- 尝试进行一次不合法的操作,例如从余额不足的账户中取款
UPDATE accounts SET balance = balance - 3000 WHERE name = 'Alice';-- 检查结果(应该看到没有变化)
SELECT * FROM accounts;-- 回滚事务以撤销这次失败的操作
ROLLBACK;-- 再次检查结果(确认一切恢复正常)
SELECT * FROM accounts;
使用保存点

保存点允许你在事务内部设置恢复点,以便部分回滚:

START TRANSACTION;-- 设置保存点
SAVEPOINT transfer_start;-- 执行转账操作
UPDATE accounts SET balance = balance - 500 WHERE name = 'Alice';
UPDATE accounts SET balance = balance + 500 WHERE name = 'Bob';-- 如果发现问题,可以回滚到保存点
ROLLBACK TO SAVEPOINT transfer_start;-- 最后不要忘记释放保存点
RELEASE SAVEPOINT transfer_start;COMMIT;

常见问题及解决方案
  • 死锁:当两个或多个事务互相等待对方释放资源时会发生死锁。可以通过优化查询、减少持有锁的时间或者调整事务隔离级别来避免。
  • 长时间持有锁:尽量缩短事务的生命周期,尽早提交或回滚事务。
  • 性能问题:高并发场景下,选择合适的锁机制和隔离级别对于性能至关重要。
总结

通过上述内容的学习,你应该已经掌握了 MySQL 事务的基本概念及其在实际应用中的使用方法。理解事务的 ACID 特性、掌握不同的锁机制以及正确设置事务隔离级别,都是编写高效且可靠的数据库应用程序的基础。希望这篇文章能够帮助你在未来的项目中更好地利用 MySQL 的事务功能,确保数据操作的安全性和一致性。


参考文献
  • MySQL 官方文档 - Transactions
  • MySQL 官方文档 - Locking

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

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

相关文章

Intel(R) Iris(R) Xe Graphics安装Anaconda、Pytorch(CPU版本)

一、Intel(R) Iris(R) Xe Graphics安装Anaconda 下载网址&#xff1a;https://repo.anaconda.com/archive/ 双击Anaconda3-2024.10-1-Windows-x86_64&#xff0c;一直下一步&#xff0c;选择安装的路径位置&#xff0c;一直下一步就安装完成了。打开Anaconda PowerShell Promp…

git使用教程(超详细)-透彻理解git

一.核心基础 核心概念有六个 首先请把与svn有关的一切概念暂时从你的脑海中移除掉&#xff0c;我们要重新认识本文所讲述的所有概念。 1.worktree worktree是一个目录&#xff0c;你在这里对文件进行增加、删除、修改。也就是我们常说的工作区。在git中worktree必须要与一个…

简单的Java小项目

学生选课系统 在控制台输入输出信息&#xff1a; 在eclipse上面的超级简单文件结构&#xff1a; Main.java package experiment_4;import java.util.*; import java.io.*;public class Main {public static List<Course> courseList new ArrayList<>();publi…

java全栈day16--Web后端实战(数据库)

一、数据库介绍 二、Mysql安装&#xff08;自行在网上找&#xff0c;教程简单&#xff09; 安装好了进行Mysql连接 连接语法&#xff1a;winr输入cmd&#xff0c;在命令行中再输入mysql -uroot -p密码 方法二&#xff1a;winr输入cmd&#xff0c;在命令行中再输入mysql -uroo…

CORDIC 算法实现 _FPGA

注&#xff1a;本文为 “CORDIC 算法” 相关文章合辑。 未整理去重。 如有内容异常&#xff0c;请看原文。 Cordic 算法的原理介绍 乐富道 2014-01-28 23:05 Cordic 算法知道正弦和余弦值&#xff0c;求反正切&#xff0c;即角度。 采用用不断的旋转求出对应的正弦余弦值&…

前端(vue组件)

1组件对象 1.1定义组件对象 defineComponent( {} ) 1.2注册组件 1.3使用组件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

MySQL八股-MVCC入门

文章目录 当前读&#xff08;加锁&#xff09;快照读&#xff08;不加锁&#xff09;MVCC隐藏字段undo-log版本链A. 第一步B.第二步C. 第三步 readview MVCC原理分析RCA. 先来看第一次快照读具体的读取过程&#xff1a;B. 再来看第二次快照读具体的读取过程: RR隔离级别 当前读…

js 函数定义域

1、1 let a 1;function fun () {console.log(a) }function fun1 () {let a 2;fun(); }fun1(); 2、2 let a 1;function fun1 () {let a 2;function fun () {console.log(a)}fun(); }fun1(); 3、2 let a 1;function fun1() {function fun() {console.log(a);}let a 2;…

羽毛球匹配项目实施清单

1. 数据库设计 1.1 数据库选型 数据库&#xff1a;MySQL理由&#xff1a;关系型数据库&#xff0c;支持复杂查询和事务处理&#xff0c;适合存储用户、匹配、聊天记录等结构化数据。 1.2 表结构设计 1.2.1 用户表&#xff08;users&#xff09; 字段名 类型 描述 id BI…

初始Python篇(6)—— 字符串

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 字符串的常见操作 格式化字符串 占位符 f-string 字符串的 format 方法 字符串的编码与解码 与数据验证相关的方法 …

vue3中的v-model如何自定义修饰符

子组件封装 <script setup lang"ts"> import { defineModel } from "vue"const firstName defineModel("first-name") // 自定义组件修饰符&#xff0c;首字母大写 const [lastName, lastNameModifiers] defineModel("last-name&q…

Mac系统Android sdk的安装

在macOS系统上安装Android SDK,通常可以通过安装Android Studio来实现,因为Android Studio默认包含了Android SDK。以下是详细的安装步骤: 一、下载并安装Android Studio 访问官网:首先,打开浏览器,访问Android Studio官方网站的下载页面。下载Android Studio:点击“Do…

Vue的常用修饰符

1.事件修饰符 stop&#xff1a;阻止事件冒泡&#xff0c;相当于调用 event.stopPropagation()。 prevent&#xff1a;阻止事件的默认行为&#xff0c;相当于调用 event.preventDefault()。 capture&#xff1a;使用事件捕获模式&#xff0c;即从最外层开始触发事件。 self&…

从 CephFS 到 JuiceFS:同程旅游亿级文件存储平台构建之路

随着公司业务的快速发展&#xff0c;同程旅行的非结构化的数据突破 10 亿&#xff0c;在 2022 年&#xff0c;同程首先完成了对象存储服务的建设。当时&#xff0c;分布式文件系统方面&#xff0c;同程使用的是 CephFS&#xff0c;随着数据量的持续增长&#xff0c;CephFS 的高…

使用Python实现手写数字识别

引言: 手写数字识别是“光学字符识别技术”(简称OCR)的一个分支,它研究的对象是:如何利用电子计算机自动辨认人手写在纸张上的阿拉伯数字。 在整个OCR领域中,最为困难的就是脱机手写字符的识别。到目前为止,尽管人们在脱机手写英文、汉字识别的研究中已取得很多可喜成就…

Jenkins参数化构建详解(This project is parameterized)

本文详细介绍了Jenkins中不同类型的参数化构建方法&#xff0c;包括字符串、选项、多行文本、布尔值和git分支参数的配置&#xff0c;以及如何使用ActiveChoiceParameter实现动态获取参数选项。通过示例展示了传统方法和声明式pipeline的语法 文章目录 1. Jenkins的参数化构建1…

深入详解线性代数基础知识:理解矩阵与向量运算、特征值与特征向量,以及矩阵分解方法(如奇异值分解SVD和主成分分析PCA)在人工智能中的应用

深入详解线性代数基础知识在人工智能中的应用 线性代数是人工智能&#xff0c;尤其是机器学习和深度学习领域的基石。深入理解矩阵与向量运算、特征值与特征向量&#xff0c;以及矩阵分解方法&#xff08;如奇异值分解SVD和主成分分析PCA&#xff09;&#xff0c;对于数据降维、…

【图像处理】利用numpy实现直方图均衡、自适应直方图均衡、对比度受限自适应直方图均衡

直方图均衡化是一种在图像处理技术&#xff0c;通过调整图像的直方图来增强图像的对比度。 本博客不利用opencv库&#xff0c;仅利用numpy、matplotlib来实现直方图均衡、自适应直方图均衡、对比度受限自适应直方图均衡 直方图均衡 包括四个流程 计算图像RGB三通道的归一化直…

Reactor 响应式编程(第三篇:R2DBC)

系列文章目录 Reactor 响应式编程&#xff08;第一篇&#xff1a;Reactor核心&#xff09; Reactor 响应式编程&#xff08;第二篇&#xff1a;Spring Webflux&#xff09; Reactor 响应式编程&#xff08;第三篇&#xff1a;R2DBC&#xff09; Reactor 响应式编程&#xff08…

组织空转数据(人类+小鼠)

空间转录组&#xff08;Spatial Transcriptomics&#xff09;是一种新兴的高通量基因组学技术&#xff0c;它允许我们在组织切片中同时获取基因表达信息和细胞的空间位置信息。其可以帮助我们更好地理解细胞在组织中的空间分布和相互作用&#xff0c;揭示组织发育、器官功能和疾…