Python能不能写一个验证事务效果的样例代码

发布时间:2026/8/9 19:53:58
Python能不能写一个验证事务效果的样例代码 很多开发者学习MySQL事务的时候只停留在理论层面不知道事务真正生效是什么样子。本文提供两套对照可运行代码无事务产生脏数据、开启事务异常自动回滚。直接运行代码观察数据库数据变化直观验证事务效果。环境准备安装依赖pipinstallpymysql测试表SQL必须使用InnoDB引擎MyISAM不支持事务。CREATETABLEaccount(idINTPRIMARYKEYAUTO_INCREMENT,usernameVARCHAR(32)NOTNULL,balanceDECIMAL(12,2)NOTNULLDEFAULT0)ENGINEInnoDBDEFAULTCHARSETutf8mb4;-- 初始化测试数据张三、李四各1000元INSERTINTOaccount(username,balance)VALUES(张三,1000.00),(李四,1000.00);业务场景张三转账200元给李四。流程张三余额扣减200模拟程序抛出异常李四余额增加200案例一不使用事务自动提交产生脏数据pymysql默认autocommitTrue每执行一条SQL就直接写入数据库。当中间代码抛出异常后面SQL无法执行就会出现一部分成功、一部分失败的数据错乱。importpymysqldefdemo_without_transaction():# 默认 autocommitTrueconnpymysql.connect(host127.0.0.1,port3306,userroot,password你的密码,databasetest_db,charsetutf8mb4)cursorconn.cursor()# 1.张三扣200这条SQL立刻生效落库cursor.execute(UPDATE account SET balance balance - %s WHERE username%s,(200,张三))# 模拟业务异常、接口报错、程序崩溃print(模拟程序发生异常)1/0# 2.李四加钱这行代码永远不会执行cursor.execute(UPDATE account SET balance balance %s WHERE username%s,(200,李四))cursor.close()conn.close()if__name____main__:demo_without_transaction()运行现象程序抛出ZeroDivisionError异常终止查询数据库张三余额变成800李四仍然1000出现脏数据钱凭空消失业务逻辑被破坏⚠️复现完成后记得重置表数据方便测试下一个案例。UPDATEaccountSETbalance1000.00;案例二开启事务异常自动回滚关键点设置conn.autocommit False关闭自动提交所有修改操作先在事务缓冲区不会真正写入数据库正常执行完毕调用conn.commit()持久化数据捕获异常调用conn.rollback()撤销全部修改importpymysqldefdemo_with_transaction():connpymysql.connect(host127.0.0.1,port3306,userroot,password你的密码,databasetest_db,charsetutf8mb4)# 关闭自动提交开启事务模式conn.autocommitFalsecursorconn.cursor()try:# 第一步张三扣款cursor.execute(UPDATE account SET balance balance - %s WHERE username%s,(200,张三))# 模拟异常触发回滚逻辑print(模拟程序发生异常)1/0# 第二步李四收款cursor.execute(UPDATE account SET balance balance %s WHERE username%s,(200,李四))# 全部执行成功提交事务数据真正写入数据库conn.commit()print(✅事务提交成功转账完成)exceptExceptionase:# 出现任何异常回滚本次事务所有变更conn.rollback()print(f❌捕获异常事务已全部回滚异常信息{e})finally:cursor.close()conn.close()if__name____main__:demo_with_transaction()运行现象异常分支程序抛出除零异常进入except代码块执行rollback()查询数据库张三、李四余额依旧都是1000数据完全没有变化所有update操作全部撤销不会产生脏数据测试正常提交场景把代码中的1 / 0注释掉再次运行。不会触发异常执行commit()数据库张三800李四1200转账业务正常完成。案例三演示部分回滚SAVEPOINT保存点MySQL支持保存点可以实现事务内部局部回滚不需要全部回滚。importpymysqldefdemo_savepoint():connpymysql.connect(host127.0.0.1,port3306,userroot,password你的密码,databasetest_db,autocommitFalse,charsetutf8mb4)curconn.cursor()try:cur.execute(UPDATE account SET balancebalance-100 WHERE username张三)# 设置保存点sp1cur.execute(SAVEPOINT sp1)cur.execute(UPDATE account SET balancebalance100 WHERE username李四)# 回滚到保存点撤销上面李四加钱操作张三扣钱保留cur.execute(ROLLBACK TO SAVEPOINT sp1)conn.commit()print(保存点演示完成)exceptExceptionase:conn.rollback()print(f异常回滚{e})finally:cur.close()conn.close()对比总结表场景无事务 autocommitTrue开启事务 autocommitFalse程序中途报错部分SQL生效生成脏数据全部操作回滚数据不变程序正常结束逐条SQL立即生效commit之后统一生效开发避坑要点autocommitFalse是开启事务的前提忘记关闭自动提交commit/rollback完全无效。同一个事务内所有SQL必须使用同一个connection对象更换连接代表全新事务。异常分支必须手动执行rollback()否则未提交事务会挂起占用数据库锁资源。表引擎必须是InnoDBMyISAM不支持事务。尽量缩小事务粒度避免长事务长事务会造成锁等待、数据库性能下降。SELECT查询语句不会修改数据不会产生事务变更SELECT ... FOR UPDATE会增加行锁。业务模板订单、库存、转账等多写业务直接套用这套模板conn.autocommitFalsetry:# 多条写sqlconn.commit()exceptException:conn.rollback()finally:conn.close()通过以上样例代码就可以直观验证MySQL事务原子性效果一组操作要么全部成功要么全部撤销。