Python使用MySQL事务的三种主流方式

 更新时间:2026年05月31日 08:24:52   作者:detayun  
本文详细讲解了如何在Python中使用MySQL事务,覆盖了pymysql、mysql-connector-python和SQLAlchemy三种主流方式,重点介绍了事务的ACID特性、常见用法及最佳实践,需要的朋友可以参考下

在实际开发中,单条 SQL 往往不够用。转账、订单处理、库存扣减……这些场景要求多条 SQL 要么全成功,要么全失败。这就是事务存在的意义。

本文用 Python 实战讲解如何正确使用 MySQL 事务,覆盖 pymysql、mysql-connector-python 和 SQLAlchemy 三种主流方式。

一、先搞懂事务的核心:ACID

特性含义举例
Atomicity(原子性)操作不可分割,全做或全不做转账:扣款和入账必须同时成功
Consistency(一致性)事务前后数据保持一致余额不能凭空消失
Isolation(隔离性)并发事务互不干扰两人同时取钱,不能互相影响
Durability(持久性)提交后数据永久保存服务器重启数据不丢失

一句话:事务就是保证数据不出乱子的机制。

二、方式一:pymysql(最常用)

2.1 基本用法

import pymysql

conn = pymysql.connect(
    host='localhost',
    user='root',
    password='your_password',
    database='test_db',
    charset='utf8mb4'
)

try:
    with conn.cursor() as cursor:
        # 开启事务(默认就是手动提交模式)
        sql1 = "UPDATE accounts SET balance = balance - 100 WHERE user_id = 1"
        sql2 = "UPDATE accounts SET balance = balance + 100 WHERE user_id = 2"
        
        cursor.execute(sql1)
        cursor.execute(sql2)
        
        # 全部成功,提交
        conn.commit()
        print("转账成功")
except Exception as e:
    # 任何一步出错,回滚
    conn.rollback()
    print(f"转账失败,已回滚:{e}")
finally:
    conn.close()

2.2 关键点

  • conn.commit() 提交事务
  • conn.rollback() 回滚事务
  • 出错必须回滚,否则已执行的 SQL 不会撤销
  • 默认 autocommit=False,所以需要手动提交

三、方式二:mysql-connector-python(官方驱动)

import mysql.connector

conn = mysql.connector.connect(
    host='localhost',
    user='root',
    password='your_password',
    database='test_db'
)

cursor = conn.cursor()

try:
    cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1")
    cursor.execute("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2")
    conn.commit()
except mysql.connector.Error as err:
    conn.rollback()
    print(f"Error: {err}")
finally:
    cursor.close()
    conn.close()

和 pymysql 逻辑一致,只是 API 略有不同。

四、方式三:SQLAlchemy ORM(推荐大型项目)

from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker, declarative_base

Base = declarative_base()

class Account(Base):
    __tablename__ = 'accounts'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    balance = Column(Integer)

engine = create_engine('mysql+pymysql://root:password@localhost/test_db')
Session = sessionmaker(bind=engine)

session = Session()

try:
    account1 = session.query(Account).filter_by(id=1).with_for_update().first()
    account2 = session.query(Account).filter_by(id=2).with_for_update().first()
    
    account1.balance -= 100
    account2.balance += 100
    
    session.commit()
    print("转账成功")
except Exception as e:
    session.rollback()
    print(f"转账失败:{e}")
finally:
    session.close()

为什么用with_for_update()?

普通查询在并发下可能读到脏数据。with_for_update() 会加行锁,确保这条记录在事务结束前不被其他事务修改,解决并发问题。

五、三种方式对比

维度pymysqlmysql-connectorSQLAlchemy
上手难度⭐⭐⭐⭐⭐⭐⭐
性能快快稍慢(有 ORM 开销)
适用场景轻量脚本、小项目官方驱动、稳定需求中大型项目
并发控制手动写 SQL手动写 SQLwith_for_update() 内置

选型建议:小项目用 pymysql,追求稳定用官方驱动,项目大了直接上 SQLAlchemy。

六、常见坑 & 最佳实践

坑1:异常没捕获,事务没回滚

# ❌ 错误示范
cursor.execute(sql1)
cursor.execute(sql2)  # 如果这里报错,sql1 已执行但没回滚
conn.commit()

必须用 try/except 包裹,except 里调用 rollback()。

坑2:连接池里的事务混乱

用连接池时,确保一个连接只处理一个事务,不要跨连接做事务操作。

坑3:忘了设置隔离级别

MySQL 默认隔离级别是 REPEATABLE READ,但有些场景需要 READ COMMITTED:

conn.begin()  # 显式开启事务
cursor.execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")

最佳实践清单

  • ✅ 事务里的 SQL 尽量少,减少锁持有时间
  • ✅ 捕获所有异常,确保回滚
  • ✅ 高并发场景加行锁(SELECT ... FOR UPDATE)
  • ✅ 生产环境用连接池(如 DBUtils、SQLAlchemy 内置池)
  • ✅ 不要在事务里做网络请求、文件 IO 等耗时操作

七、总结

你的场景推荐方案
写个脚本批量处理数据pymysql + 手动 commit/rollback
官方项目,求稳定mysql-connector-python
Web 项目、多人协作SQLAlchemy + with_for_update()

事务不复杂,但用错了比不用更危险。记住三个动作:begin → commit / rollback → close,就能覆盖 90% 的场景。

以上就是Python使用MySQL事务的三种主流方式的详细内容,更多关于Python使用MySQL事务的资料请关注脚本之家其它相关文章!

相关文章

  • Python基础知识学习之类的继承

    Python基础知识学习之类的继承

    今天带大家学习Python的基础知识,文中对python类的继承作了非常详细的介绍,对正在学习python基础的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • python全自动脚本实现翻译英文pdf文件

    python全自动脚本实现翻译英文pdf文件

    在全球化的今天,跨越语言障碍获取信息变得尤为重要,本文将介绍几种有效的方法,帮助您将英文PDF文件完整地翻译成中文,需要的小伙伴可以参考一下
    2025-08-08
  • Python文件操作和异常处理的方法和技巧

    Python文件操作和异常处理的方法和技巧

    本文介绍了Python文件操作和异常处理的方法和技巧,包括读写文本文件、读写二进制文件、文件指针、异常类型和处理、try-except语句、异常处理程序等内容,帮助读者更好地掌握Python在文件操作和异常处理方面的应用
    2023-05-05
  • PyQt5实现暗黑风格的计时器

    PyQt5实现暗黑风格的计时器

    这篇文章主要为大家详细介绍了PyQt5实现暗黑风格的计时器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 基于Python中的yield表达式介绍

    基于Python中的yield表达式介绍

    今天小编就为大家分享一篇基于Python中的yield表达式详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Pycharm shell配置带你解决Pycharm终端进不了conda虚拟环境的情况

    Pycharm shell配置带你解决Pycharm终端进不了conda虚拟环境的情况

    这篇文章主要介绍了Pycharm shell配置带你解决Pycharm终端进不了conda虚拟环境的情况,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2026-05-05
  • python读取.data文件的实现

    python读取.data文件的实现

    本文主要介绍了python读取.data文件的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Python操作MySQL数据库实践

    Python操作MySQL数据库实践

    本文详细介绍了Python操作MySQL数据库的全流程技术,从基础连接库安装、CRUD操作,到进阶的连接池优化、事务管理与隔离级别,并补充了异常处理、SQL注入防护、批量操作优化等知识点,帮助读者掌握Python操作MySQL的核心技能,适用于运维开发及数据库学习者
    2026-04-04
  • python 使用递归回溯完美解决八皇后的问题

    python 使用递归回溯完美解决八皇后的问题

    今天小编就为大家分享一篇python 使用递归回溯完美解决八皇后的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • 详解从Django Rest Framework响应中删除空字段

    详解从Django Rest Framework响应中删除空字段

    这篇文章主要介绍了详解从Django Rest Framework响应中删除空字段,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01

最新评论