在开发中,使用 Python 操作 MySQL 数据库时,事务处理 是保证数据一致性的关键。本文将通过一个真实的 转账案例,带你掌握 try-except-finally 的完整流程。
1. 目标:实现 A 账户向 B 账户转账
假设我们有两个账户:
转账操作需要完成两步:
核心要求:这两步必须 同时成功,才算转账完成。如果第一步成功、第二步失败,A 账户的钱扣了,B 账户却没收到,就会导致数据不一致。
2. 代码实现:使用 try-except-finally 保证事务完整性
下面是一段完整的 Python 代码,使用 pymysql 连接 MySQL,并利用事务机制完成转账:
import pymysqlconnection = Nonetry: connection = pymysql.connect( host="localhost", user="root", password="你的密码", database="bank", charset="utf8mb4", autocommit=False, ) with connection.cursor() as cursor: # 账户A扣除100元 cursor.execute( """ UPDATE account SET balance = balance - %s WHERE id = %s """, (100, 1), ) # 账户B增加100元 cursor.execute( """ UPDATE account SET balance = balance + %s WHERE id = %s """, (100, 2), ) # 所有SQL都成功后再提交 connection.commit() print("转账成功")except pymysql.MySQLError as error: # 撤销当前事务中的修改 if connection is not None: connection.rollback() print(f"数据库操作失败:{error}") raisefinally: # 无论成功还是失败,都释放连接 if connection is not None: connection.close()
3. 测试:模拟成功与失败场景
场景一:正常转账(两条 SQL 都成功)
执行 transfer() 函数,控制台输出:
查询数据库,A 账户余额变为 900 元,B 账户余额变为 600 元。
场景二:模拟第二步失败(比如 B 账户不存在)
修改代码,故意让第二条 SQL 报错:
sql_b = "UPDATE accounts SET balance = balance + 100 WHERE account_id = 'C'" # C 不存在执行后,控制台输出:
查询数据库,A 账户余额仍然是 1000 元,没有变化。这就是 回滚 的作用——回到转账前的状态。
4. 结果分析
关键机制:
•commit:只有两条 SQL 都成功,才提交到数据库。•rollback:只要有一条 SQL 失败,就撤销所有操作,回到原始状态。•close:无论成功失败,最后都要关闭游标和连接,释放资源。
5. 小结:三句话记住事务处理
全部成功 commit,任何失败 rollback,最后无论结果如何 close。
•try 块:执行所有 SQL 操作,全部成功则 commit。•except 块:捕获异常,执行 rollback 回滚,并 raise 抛出异常便于定位。•finally 块:执行 close 关闭连接,释放资源。在实际项目中(如 Django、FastAPI),ORM 框架已经封装了这些底层操作,你只需调用 transaction.atomic() 等高级 API 即可。但理解底层的 try-except-finally 机制,能让你更清楚事务的本质。
如果你对 Django 或 FastAPI 中的事务操作感兴趣,欢迎跟着我们的课程系统学习!
【Djano+Vue全栈开发体系大课】https://study.163.com/course/courseMain.htm?courseId=1213432812&share=2&shareId=480000001946434
【FastAPI+AI体系大课】https://study.163.com/course/courseMain.htm?courseId=1223953802&share=2&shareId=480000001946434