《MySQL 简易速速上手小册》第8章:事务管理和锁定策略(2024 最新版)

在这里插入图片描述

文章目录

  • 8.1 理解 MySQL 中的事务
    • 8.1.1 基础知识
    • 8.1.2 重点案例:使用 Python 实现银行转账事务
    • 8.1.3 拓展案例 1:处理并发事务
    • 8.1.4 拓展案例 2:使用 Python 监控事务状态
  • 8.2 锁定机制和事务隔离级别
    • 8.2.1 基础知识讲解
    • 8.2.2 重点案例:使用 Python 演示不同事务隔离级别的影响
    • 8.2.3 拓展案例 1:解决幻读问题
    • 8.2.4 拓展案例 2:使用锁定机制管理并发更新
  • 8.3 避免和解决死锁
    • 8.3.1 基础知识
    • 8.3.2 重点案例:使用 Python 检测并响应死锁
    • 8.3.3 拓展案例 1:优化事务设计以避免死锁
    • 8.3.4 拓展案例 2:使用 SHOW ENGINE INNODB STATUS 分析死锁

8.1 理解 MySQL 中的事务

事务是数据库管理的基石,确保了数据的完整性和一致性。在MySQL的世界里,事务就像是一场精心策划的表演,每个动作都要按照既定的剧本(也就是事务的四大特性ACID:原子性、一致性、隔离性、持久性)来执行。

8.1.1 基础知识

  • 原子性(Atomicity):事务是不可分割的工作单位,要么全部完成,要么全部不做。
  • 一致性(Consistency):事务执行前后,数据库从一个一致性状态转移到另一个一致性状态。
  • 隔离性(Isolation):一个事务的执行不能被其他事务干扰。
  • 持久性(Durability):一旦事务提交,其结果就永久保存在数据库中。

8.1.2 重点案例:使用 Python 实现银行转账事务

假设你正在开发一个在线银行系统,需要处理用户之间的转账操作,这是一个经典的事务处理场景。

建立数据库连接,并开启一个事务。

import mysql.connector
from mysql.connector import Errortry:# 连接数据库conn = mysql.connector.connect(host='localhost', user='user', password='password', database='bank')conn.start_transaction()cursor = conn.cursor()# 执行转账操作# 从账户A扣款cursor.execute("UPDATE accounts SET balance = balance - %s WHERE account_id = %s", (100, 'A'))# 向账户B加款cursor.execute("UPDATE accounts SET balance = balance + %s WHERE account_id = %s", (100, 'B'))# 检查账户A的余额是否足够cursor.execute("SELECT balance FROM accounts WHERE account_id = 'A'")balance = cursor.fetchone()[0]if balance < 0:raise Exception("Insufficient funds")# 提交事务conn.commit()print("Transfer successful")
except Error as e:print(f"Error: {e}")conn.rollback()print("Transaction failed and rolled back")
finally:if conn.is_connected():cursor.close()conn.close()

8.1.3 拓展案例 1:处理并发事务

在高并发环境下,多个事务可能同时操作同一数据,增加了冲突的可能性。使用隔离级别来控制事务的可见性。

# 假设已经有了数据库连接 conn
conn.start_transaction(isolation_level='REPEATABLE READ')
# 然后继续你的数据库操作

8.1.4 拓展案例 2:使用 Python 监控事务状态

在复杂的系统中,监控事务的状态和性能是非常重要的。使用 INFORMATION_SCHEMA.INNODB_TRX 表来获取当前运行的事务信息。

cursor.execute("SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX")
transactions = cursor.fetchall()
for trx in transactions:print(trx)

通过以上案例,你学会了如何在实际的应用中使用Python来处理MySQL事务,确保数据的安全和一致性,即使在面对并发和复杂业务逻辑时也能保持系统的稳定性。这些技能在开发安全、可靠的应用程序时非常重要,能够帮助你构建更加健壮的数据处理逻辑。

在这里插入图片描述


8.2 锁定机制和事务隔离级别

在MySQL的奇妙世界里,锁定机制和事务隔离级别是维持数据完整性和并发控制的魔法工具。理解它们的工作原理就像学会了控制时间和空间,让你能够在数据的海洋中自如航行,即使面对最复杂的并发挑战。

8.2.1 基础知识讲解

  • 锁定机制:MySQL使用锁来管理对共享资源的并发访问。锁有多种类型,包括共享锁(读锁)和排他锁(写锁)。
  • 事务隔离级别:决定了一个事务所做的更改在哪些情况下对其他事务可见,它影响着并发事务的可见性和效率。MySQL支持四种标准的事务隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ(默认级别)、SERIALIZABLE。

8.2.2 重点案例:使用 Python 演示不同事务隔离级别的影响

假设你想通过实验观察不同事务隔离级别对并发读写操作的影响。

步骤

  1. 创建两个并行运行的Python脚本,一个用于读取数据,另一个用于修改数据。

  2. 在读取数据的脚本中,设置事务隔离级别,并查询数据。

    import mysql.connector
    from threading import Threaddef read_data(isolation_level):conn = mysql.connector.connect(user='user', password='password', host='localhost', database='testdb')conn.start_transaction(isolation_level=isolation_level)cursor = conn.cursor()cursor.execute("SELECT * FROM test_table")for row in cursor.fetchall():print(row)cursor.close()conn.close()def update_data():conn = mysql.connector.connect(user='user', password='password', host='localhost', database='testdb')cursor = conn.cursor()cursor.execute("UPDATE test_table SET value = value + 1 WHERE id = 1")conn.commit()cursor.close()conn.close()Thread(target=read_data, args=('REPEATABLE READ',)).start()
    Thread(target=update_data).start()
    

8.2.3 拓展案例 1:解决幻读问题

幻读是在REPEATABLE READ隔离级别下一个常见的问题,其中一个事务读取到了另一个事务插入的行。

使用SERIALIZABLE隔离级别来防止幻读,修改上述读取数据的脚本部分设置隔离级别。

# 修改 read_data 函数中的 isolation_level 参数为 'SERIALIZABLE'
Thread(target=read_data, args=('SERIALIZABLE',)).start()

8.2.4 拓展案例 2:使用锁定机制管理并发更新

在高并发环境下,正确管理并发更新至关重要。下面的例子演示了如何使用排他锁来确保数据更新的原子性。

def concurrent_update(task_id):conn = mysql.connector.connect(user='user', password='password', host='localhost', database='testdb', autocommit=False)cursor = conn.cursor()try:cursor.execute("SELECT value FROM test_table WHERE id = 1 FOR UPDATE")value = cursor.fetchone()[0]print(f"Task {task_id}: Current Value: {value}")cursor.execute("UPDATE test_table SET value = %s WHERE id = 1", (value + 1,))conn.commit()print(f"Task {task_id}: Updated Value: {value + 1}")except mysql.connector.Error as e:print(f"Task {task_id}: Error: {e}")conn.rollback()finally:cursor.close()conn.close()for i in range(5):  # 模拟5个并发更新Thread(target=concurrent_update, args=(i,)).start()

通过上述案例,你已经学会了如何在Python中使用MySQL的锁定机制和事务隔离级别来管理并发访问和更新,确保数据的一致性和完整性。这些技能在开发需要高并发处理的应用时极其宝贵,帮助你构建更加健壮和可靠的系统。

在这里插入图片描述


8.3 避免和解决死锁

在MySQL的迷宫中,死锁是那些不请自来的访客,它们在不经意间将数据的流动锁在一个无法前进也无法后退的困境。理解死锁的本质和解决方案就像是掌握了一把打开任何锁的钥匙,让你能够自如地导航在数据的海洋。

8.3.1 基础知识

  • 死锁的原因:死锁通常发生在多个事务并发访问相同资源时,每个事务持有一部分资源同时等待其他资源释放。
  • 死锁的检测与解决:MySQL有内建的死锁检测机制,能够自动检测并解决死锁,通常是通过回滚事务中修改最少的那个来解决。
  • 避免死锁的策略:包括但不限于保持一致的锁定顺序、减少事务持有锁的时间、使用锁定的最小数据集。

8.3.2 重点案例:使用 Python 检测并响应死锁

假设你正在运行一个需要高事务吞吐量的应用,你想通过自动化方式监控死锁并作出响应。

周期性地检查 INFORMATION_SCHEMA.INNODB_LOCKSINFORMATION_SCHEMA.INNODB_LOCK_WAITS 表来监控潜在的死锁。

import mysql.connector
import timedef check_for_deadlocks():conn = mysql.connector.connect(user='user', password='password', host='localhost', database='information_schema')cursor = conn.cursor()deadlock_query = """SELECT lw.requesting_trx_id, lw.blocking_trx_idFROM INNODB_LOCK_WAITS lwJOIN INNODB_LOCKS l ON lw.requested_lock_id = l.lock_idJOIN INNODB_LOCKS bl ON lw.blocking_lock_id = bl.lock_id;"""cursor.execute(deadlock_query)deadlocks = cursor.fetchall()for deadlock in deadlocks:print(f"Deadlock detected: {deadlock}")cursor.close()conn.close()while True:check_for_deadlocks()time.sleep(60)  # Check every minute

8.3.3 拓展案例 1:优化事务设计以避免死锁

在设计事务时,确保按照相同的顺序获取锁可以减少死锁的可能性。

def transfer_amount(from_account, to_account, amount):conn = mysql.connector.connect(user='user', password='password', host='localhost', database='your_db')cursor = conn.cursor()# 按照账户ID的顺序加锁accounts = sorted([from_account, to_account])cursor.execute("SELECT * FROM accounts WHERE account_id IN (%s, %s) FOR UPDATE", (accounts[0], accounts[1]))# 执行转账逻辑...# 省略详细代码cursor.close()conn.close()

8.3.4 拓展案例 2:使用 SHOW ENGINE INNODB STATUS 分析死锁

当死锁发生时,使用 SHOW ENGINE INNODB STATUS 获取更详细的死锁信息,帮助分析原因。

def analyze_deadlocks():conn = mysql.connector.connect(user='user', password='password', host='localhost', database='your_db')cursor = conn.cursor()cursor.execute("SHOW ENGINE INNODB STATUS")status = cursor.fetchone()print(status[2])  # 死锁信息通常在第三个字段cursor.close()conn.close()analyze_deadlocks()

通过上述案例,你学会了如何使用 Python 监控、分析和避免 MySQL 中的死锁,这些技能将帮助你提升数据库的稳定性和性能。掌握了如何应对死锁,你就能确保你的数据库事务能够在高并发环境下平稳运行,无惧任何挑战。

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

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

相关文章

迷你世界勒索病毒,你的文件被删了吗?

前言 笔者在某恶意软件沙箱平台分析样本的时候&#xff0c;发现了一款比较有意思的勒索病毒MiniWorld迷你世界勒索病毒&#xff0c;它的解密界面与此前的WannaCry勒索病毒的界面相似&#xff0c;应该是作者仿冒的WannaCry的UI&#xff0c;如下所示&#xff1a; 这款勒索病毒既…

【OrangePi Zero2的系统移植】交叉编译工具链配置、wiringOP库、智能分类工程代码

一、交叉编译工具链配置 二、交叉编译wiringOP库 三、交叉编译智能分类工程代码 四、Makefile 用于编译 WiringPi 库 一、交叉编译工具链配置 1、关于编译 编译是指将源代码文件&#xff08;如C/C文件&#xff09;经过预处理、编译、汇编和链接等步骤&#xff0c;转换为可执…

发廊理发店微信小程序展示下单前端静态模板源码

模板描述&#xff1a;剪发小程序前端源码&#xff0c;一共五个页面&#xff0c;包括店铺、理发师、订单、我的等页面 注&#xff1a;该源码是前端静态模板源码&#xff0c;没有后台和API接口

如何用Hexo搭建一个优雅的博客

引言 在数字化时代&#xff0c;拥有一个个人博客已经成为许多人展示自己技能、分享知识和与世界互动的重要方式。而在众多博客平台中&#xff0c;Hexo因其简洁、高效和易于定制的特点而备受青睐。本文将详细介绍如何从零开始搭建一个Hexo博客&#xff0c;让你的个人博客在互联…

Lombok 高级说明

优质博文&#xff1a;IT-BLOG-CN 一、痛点 【1】代码臃肿&#xff1a;POJO中的getter/setter/equals/hashcode/toString等&#xff1b; 【2】样板式代码&#xff1a;I/O流的关闭操作等&#xff1b; Lombok是一个可以通过注解简化Java代码开发的工具&#xff0c;能够在我们编…

虚继承 -- 解决菱形继承问题以及无法跨继承访问

目录 什么是菱形继承? 菱形继承造成的问题: 如何解决这种问题: 代码分析: 注意: 什么是菱形继承? 上图就是一个菱形继承的例子。 菱形继承: 有两个类(Father,Mother)&#xff0c;都继承于一个类(Human),然后还有一个类&#xff0c;又同时继承于这两个类(Son)…

CentOS 7安装Nodejs

说明&#xff1a;本文介绍如何在云服务器上CentOS 7操作系统上安装Nodejs。以及安装过程中遇到的问题。 下载压缩包&解压 首先&#xff0c;先去官网下载Linux版本的Node。 将下载下来的压缩包&#xff0c;上传到云服务器上&#xff0c;解压。配置环境变量。 &#xff08…

保护我方水晶,2024 数据库安全工具盘点

在数据价值堪比石油的数字时代&#xff0c;对每个组织而言&#xff0c;保护这一核心资产显得尤为重要。无论是来自外部的黑客攻击和恶意软件&#xff0c;还是源于内部的人为失误和内鬼行为&#xff0c;威胁无处不在。本文将介绍几款先进的数据库安全工具&#xff0c;从不同维度…

统一数据格式返回,统一异常处理

目录 1.统一数据格式返回 2.统一异常处理 3.接口返回String类型问题 1.统一数据格式返回 添加ControllerAdvice注解实现ResponseBodyAdvice接口重写supports方法&#xff0c;beforeBodyWrite方法 /*** 统一数据格式返回的保底类 对于一些非对象的数据的再统一 即非对象的封…

FastDFS安装并整合Openresty

FastDFS安装 一、环境--centos7二、FastDFS--tracker安装2.1.下载2.2.FastDFS安装环境2.3.安装FastDFS依赖libevent库2.4.安装libfastcommon2.5.安装 libserverframe 网络框架2.6.tracker编译安装2.7.文件安装位置介绍2.8.错误处理2.9.配置FastDFS跟踪器(Tracker)2.10.启动2.11…

【MySQL进阶之路】BufferPool 生产环境优化经验

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

【开源】基于JAVA+Vue+SpringBoot的假日旅社管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四、核心代码4.1 查询民宿4.2 新增民宿评论4.3 查询民宿新闻4.4 新建民宿预订单4.5 查询我的民宿预订单 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的假日旅社…