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

news2024/11/19 17:36:17

在这里插入图片描述

文章目录

  • 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 Error

try:
    # 连接数据库
    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 Thread
    
    def 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 time

def 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_id
    FROM INNODB_LOCK_WAITS lw
    JOIN INNODB_LOCKS l ON lw.requested_lock_id = l.lock_id
    JOIN 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.coloradmin.cn/o/1442775.html

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

相关文章

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(12)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;11&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备…

Java强训day14(选择题编程题)

选择题 编程题 题目1 import java.util.Scanner;public class Main {public static void main(String[] args) {//读入年月日&#xff08;字符串形式读入&#xff09;Scanner sc new Scanner(System.in);String s sc.nextLine();String[] ss s.split(" ");i…

C语言学习day12:水仙花(do while)

前面我们学习了do while循环&#xff0c;今天做一个练习&#xff1a;水仙花 题目&#xff1a;一个三位数&#xff08;100-999&#xff09;&#xff0c;获取其中所有各个位数的相加等于这个数本身 的数 尽量自己先写一写&#xff0c;差不多了再看答案 思路&#xff1a; 先获…

【医学大模型 尘肺病】PneumoLLM:少样本大模型诊断尘肺病新方法

PneumoLLM&#xff1a;少样本大模型诊断尘肺病新方法 提出背景PneumoLLM 框架效果 提出背景 论文&#xff1a;https://arxiv.org/pdf/2312.03490.pdf 代码&#xff1a;https://github.com/CodeMonsterPHD/PneumoLLM/tree/main 历史问题及其背景&#xff1a; 数据稀缺性问题&a…

HarmonyOS 鸿蒙 ArkTS 双色旋转动画效果

下载地址&#xff1a; https://download.csdn.net/download/weixin_54226053/88818859 也可以点击顶部的资源下载

88 SRC挖掘-拿下CNVD证书开源闭源售卖系统

目录 1&#xff0e;开源系统、闭源系统、售卖系统2&#xff0e;如何寻找上述三类系统并进行安全测试3&#xff0e;如何挑简单的入手最快速度获取证书装x演示案例:某开源逻辑审计配合引擎实现通用某闭源审计或黑盒配合引擎实现通用某售卖审计或黑盒配合引擎实现通用 涉及资源&am…

手撸一个M3U8下载插件

M3U8嗅探下载 思路与核心代码 基本思路 ​ M3U8视频格式是一种基于HTTP Live Streaming&#xff08;HLS&#xff09;协议的视频文件格式。它是苹果公司开发的&#xff0c;目前广泛应用于iOS、macOS和tvOS等系统中。与传统的视频格式不同&#xff0c;M3U8视频格式将整个视频分…

Nginx 配置 SSL证书

成功配置SSL证书后&#xff0c;您将能够通过HTTPS加密通道安全访问Nginx服务器。 一、准备材料 SSL证书绑定的域名已完成DNS解析&#xff0c;即您的域名与主机IP地址相互映射。您可以通过DNS验证证书工具&#xff0c;检测域名DNS解析是否生效。具体操作&#xff1a; 【1】登录…

双活工作关于nacos注册中心的数据迁移

最近在做一个双活的项目&#xff0c;在纠结一个注册中心是在双活机房都准备一个&#xff0c;那主机房的数据如果传过去呢&#xff0c;查了一些资料&#xff0c;最终在官网查到了一个NacosSync 的组件&#xff0c;主要用来做数据传输的&#xff0c;并且支持在线替换注册中心的&a…

重返达沃斯!YGG 联合创始人 Beryl Li 参加世界经济论坛 2024 年年会

Yield Guild Games&#xff08;YGG&#xff09;联合创始人 Beryl Li 代表公会再次来到瑞士达沃斯&#xff0c;参加了 2024 年 1 月 14 日至 19 日举行的世界经济论坛 2024 年年会&#xff08;WEF24&#xff09;。在她的小组讨论中&#xff0c;她谈到了缩小发展中国家的技术差距…

分布式session 笔记

概念 解决方案‘ 复制 session同步&#xff0c;让集群下的服务器进行session同步&#xff0c;一种传统的服务器集群session管理机制&#xff0c;常用于服务器不多的集群环境。<br /> 集群下&#xff0c;进行session同步的服务器的session数据是相同的&#xff0c;…

【Java EE初阶十二】网络初识

1. 网络发展史 网络发展的几个主要时期&#xff1a; 单机时代->局域网时代->广域网时代->移动互联网时代 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同工作来完成 业务&#xff0c;就有了网络互…

1 月 NFT 市场动态:Polygon 增长,Mooar 崛起,TinFun 掀起文化浪潮

作者&#xff1a;stellafootprint.network 数据源&#xff1a;NFT Research - Footprint Analytics 2024 年 1 月&#xff0c;加密货币与 NFT 市场迎来了重要的转折点&#xff0c;其中美国首批现货比特币 ETF 的亮相尤为引人注目&#xff0c;这一金融一体化的里程碑事件吸引了…

常见云计算服务模式( IaaS基础架构即服务、PaaS平台即服务、SaaS软件即服务)

常见云计算服务模式 &#xff08; IaaS基础架构即服务、PaaS平台即服务、SaaS软件即服务&#xff09; 零、00时光宝盒 世界并不完美&#xff0c;面对很多事情我们都很无奈甚至悲哀&#xff0c;但生活总要继续下去&#xff0c;不止是为了自己。抱怨没有用&#xff0c;顾影自怜也…

react中hook封装一个table组件 与 useColumns组件

目录 1&#xff1a;react中hook封装一个table组件依赖CommonTable / index.tsx使用组件效果 2&#xff1a;useColumns组件useColumns.tsx使用 1&#xff1a;react中hook封装一个table组件 依赖 cnpm i react-resizable --save cnpm i ahooks cnpm i --save-dev types/react-r…

【Java面试】数据类型常见面试题

什么是包装类型 将基本类型包装进了对象中得到的类型 基本类型和包装类型有什么区别 用途不同&#xff1a;基本类型一般用于局部变量&#xff0c;包装类型用于其他地方存储方式不同&#xff1a;用于局部变量的基本类型存在虚拟机栈中的局部变量表中&#xff0c;用于成员变量…

蓝桥杯刷题day07——斐波那契与7

1、题目描述 斐波那契数列的递推公式为:FnFn-1Fn-2, 其中F1F21. 请问, 斐波那契数列的第 1 至 202202011200 项&#xff08;含&#xff09;中, 有多少项的个位 是 7 。 答案提交 这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填…

2024年低压电工证模拟考试题库及低压电工理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年低压电工证模拟考试题库及低压电工理论考试试题是由安全生产模拟考试一点通提供&#xff0c;低压电工证模拟考试题库是根据低压电工最新版教材&#xff0c;低压电工大纲整理而成&#xff08;含2024年低压电工证…

Unity3D学习之UI系统——UGUI

文章目录 1. 前言2 六大基础组件概述3 Canvas——渲染模式的控制3.1 Canvas作用3.2 Canvas的渲染模式3.2.1 Screen Space -Overlay 覆盖模式3.2.2 Screen Space - Camera 摄像机模式3.2.3 World Space 4 CanvasScaler ——画布缩放控制器4.1 Constant Pixel Size 恒定像素模式4…

【微机原理与单片机接口技术】MCS-51单片机的引脚功能介绍

前言 MCS-51是指由美国Intel公司生产的一系列单片机的总称。MCS-51系列单片机型号有很多&#xff0c;按功能分位基本型和增强型两大类&#xff0c;分别称为8051系列单片机和8052系列单片机&#xff0c;两者以芯片型号中的末位数字区分&#xff0c;1为基本型&#xff0c;2为增强…