Python 使用 MySQL 數(shù)據(jù)庫進行事務處理完整示例
一、事務核心概念(先理解再實操)
事務(Transaction)是數(shù)據(jù)庫操作的最小邏輯單元,遵循 ACID 原則:
- 原子性(Atomicity):要么全部執(zhí)行成功,要么全部失敗回滾
- 一致性(Consistency):執(zhí)行前后數(shù)據(jù)庫狀態(tài)保持一致
- 隔離性(Isolation):多個事務互不干擾
- 持久性(Durability):提交后數(shù)據(jù)永久保存
Python操作MySQL時,默認是自動提交(autocommit) 模式(執(zhí)行單條SQL會立即生效),而事務處理需要先關閉自動提交,手動控制提交/回滾。
二、完整事務處理代碼示例
以「轉賬場景」為例(經(jīng)典的事務應用場景:A賬戶扣錢、B賬戶加錢,必須同時成功/失?。?/p>
import mysql.connector
from mysql.connector import Error
def transfer_money(from_id, to_id, amount):
"""
模擬轉賬的事務處理
:param from_id: 轉出賬戶ID
:param to_id: 轉入賬戶ID
:param amount: 轉賬金額
"""
connection = None
try:
# 1. 建立數(shù)據(jù)庫連接
connection = mysql.connector.connect(
host='localhost',
user='root',
password='123456',
database='test_db'
)
# 2. 關閉自動提交,開啟手動事務控制
connection.autocommit = False
cursor = connection.cursor()
# 3. 執(zhí)行事務內(nèi)的多個SQL操作
# 步驟1:扣除轉出賬戶金額
deduct_sql = "UPDATE account SET balance = balance - %s WHERE id = %s"
cursor.execute(deduct_sql, (amount, from_id))
# 步驟2:增加轉入賬戶金額
add_sql = "UPDATE account SET balance = balance + %s WHERE id = %s"
cursor.execute(add_sql, (amount, to_id))
# 模擬異常(可取消注釋測試回滾效果)
# raise Error("模擬轉賬異常,觸發(fā)回滾")
# 4. 所有操作執(zhí)行成功,提交事務
connection.commit()
print("轉賬成功!事務已提交")
except Error as e:
# 5. 發(fā)生異常,回滾事務(撤銷所有已執(zhí)行的SQL操作)
if connection:
connection.rollback()
print(f"轉賬失敗,事務已回滾!錯誤信息:{e}")
finally:
# 6. 釋放資源(關閉游標和連接)
if connection and connection.is_connected():
cursor.close()
# 恢復自動提交(可選,不影響,但規(guī)范)
connection.autocommit = True
connection.close()
print("數(shù)據(jù)庫連接已關閉")
# ==================== 測試前準備 ====================
# 先在MySQL中創(chuàng)建測試表和數(shù)據(jù):
# CREATE DATABASE IF NOT EXISTS test_db;
# USE test_db;
# CREATE TABLE IF NOT EXISTS account (
# id INT PRIMARY KEY,
# name VARCHAR(50),
# balance DECIMAL(10,2)
# );
# INSERT INTO account (id, name, balance) VALUES (1, '張三', 1000.00), (2, '李四', 500.00);
# ==================== 執(zhí)行轉賬測試 ====================
# 測試正常轉賬(張三給李四轉200元)
transfer_money(from_id=1, to_id=2, amount=200.00)三、關鍵操作解釋
- 關閉自動提交:
connection.autocommit = False是開啟事務的核心,關閉后執(zhí)行的SQL不會立即生效,需手動commit()。 - 事務提交:
connection.commit()僅當所有SQL執(zhí)行無異常時調(diào)用,會將事務內(nèi)所有操作永久寫入數(shù)據(jù)庫。 - 事務回滾:
connection.rollback()僅在捕獲到異常時調(diào)用,會撤銷事務內(nèi)所有已執(zhí)行的SQL操作,恢復到事務開始前的狀態(tài)。 - 異常捕獲:
必須用try-except包裹所有事務內(nèi)的操作,確保任何錯誤都能觸發(fā)回滾,避免數(shù)據(jù)不一致。
四、拓展場景:批量操作事務
如果需要批量插入/更新多條數(shù)據(jù),事務同樣適用,示例如下:
def batch_insert_users(users):
"""批量插入用戶,使用事務保證全部成功/失敗"""
connection = None
try:
connection = mysql.connector.connect(
host='localhost',
user='root',
password='123456',
database='test_db'
)
connection.autocommit = False
cursor = connection.cursor()
insert_sql = "INSERT INTO user (name, age) VALUES (%s, %s)"
# 批量執(zhí)行SQL(效率更高)
cursor.executemany(insert_sql, users)
connection.commit()
print(f"批量插入 {cursor.rowcount} 條數(shù)據(jù)成功")
except Error as e:
if connection:
connection.rollback()
print(f"批量插入失敗,事務回滾:{e}")
finally:
if connection and connection.is_connected():
cursor.close()
connection.autocommit = True
connection.close()
# 測試批量插入
user_list = [("王五", 30), ("趙六", 28), ("孫七", 35)]
batch_insert_users(user_list)到此這篇關于Python 使用 MySQL 數(shù)據(jù)庫進行事務處理步驟的文章就介紹到這了,更多相關python mysql事務 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Python實現(xiàn)音樂節(jié)奏可視化效果
這篇文章主要為大家詳細介紹了如何基于Python語言實現(xiàn)音樂節(jié)奏可視化效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2023-06-06
python游戲?qū)崙?zhàn)項目之俄羅斯方塊的魅力
遲早一定會掛掉的俄羅斯方塊,為什么至今仍是世界游戲之王?它是怎么編寫的?本文將給大家詳細的介紹,對大家的學習或工作具有一定的參考借鑒價值2021-09-09
Python爬蟲headers處理及網(wǎng)絡超時問題解決方案
這篇文章主要介紹了Python爬蟲headers處理及網(wǎng)絡超時問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06
Python采集熱搜數(shù)據(jù)實現(xiàn)詳解
這篇文章主要為大家介紹了Python采集熱搜數(shù)據(jù)實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05

