当前位置: 首页 > article >正文

理解数据库事务和回滚:概念、实例与Python脚本实现

文章目录

    • 概念
    • 银行案例实践
      • 创建数据
      • Python脚本中的事务回滚
    • 结语:保障数据安全与完整性的关键

概念

  • 事务(Transaction): 数据库中的事务是一组不可分割的操作集合,它们要么全部成功,要么全部失败。这个概念保证了数据的完整性和一致性。
  • 回滚(Rollback): 当事务中的一个或多个操作失败时,回滚机制会撤销所有已执行的操作,将数据库恢复到事务开始前的状态。这是一种错误恢复机制。
  • 提交(Commit): 如果事务中的所有操作都成功完成,那么事务会被提交,其结果会永久地保存在数据库中。
  • ACID属性:
    1)原子性(Atomicity): 确保事务中的所有操作都作为一个整体来执行。
    2)一致性(Consistency): 事务的执行保证了数据库从一个一致的状态转移到另一个一致的状态。
    3)隔离性(Isolation): 确保并发执行的事务彼此独立,不会相互干扰。
    4)持久性(Durability): 一旦事务提交,其结果在数据库中持久保存。

银行案例实践

创建数据

本例中,我们创建一个名为 accounts 的表,包含 account_id(账户ID,作为主键)和 balance(账户余额)两个字段。脚本将插入两个账户A和B,各自具有特定的初始余额。

-- 创建银行账户表
CREATE TABLE test.accounts (
    account_id VARCHAR(10) PRIMARY KEY,
    balance DECIMAL(10, 2) NOT NULL
);

-- 插入初始数据
INSERT INTO test.accounts (account_id, balance) VALUES ('A', 1000.00);  -- 假设账户A有1000元
INSERT INTO test.accounts (account_id, balance) VALUES ('B', 500.00);   -- 假设账户B有500元

Python脚本中的事务回滚

以下Python脚本演示了如何在数据库操作中使用事务。脚本开始于 connection.begin(),标志着事务的开始,并尝试执行两个账户间的转账操作。任何操作的失败都将触发异常,执行 connection.rollback(),撤销所有更改。若操作成功,则通过 connection.commit() 提交事务。

import pandas as pd
import pymysql
from credentials import get_credentials
import datetime


def connect_to_database():
    credentials = get_credentials()

    connection = pymysql.connect(
        host='localhost',
        user=credentials['username'],
        password=credentials['password'],
        database='test',
        charset='utf8mb4',
        cursorclass=pymysql.cursors.DictCursor
    )

    try:
        with connection.cursor() as cursor:
            current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            print(f"{current_time} - 开始事务")
            connection.begin()

            sql_statements = [
                "UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A'",
                "UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B'",
                "select * from accounts;"
            ]

            for sql_statement in sql_statements:
                try:
                    # 执行 SQL 语句
                    cursor.execute(sql_statement)

                    # 获取查询结果
                    result = cursor.fetchall()
                    df = pd.DataFrame(result)

                    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

                    print(f"{current_time} - 正在执行sql: {sql_statement}")
                    print(f"{current_time} - 查询结果如下:")
                    print(df)
                except pymysql.MySQLError as e:
                    # 发生错误时记录错误并准备回滚
                    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                    print(f"{current_time} - SQL 错误: {e}")
                    connection.rollback()
                    print("Transaction rolled back.")
                    return  # 结束函数,不再执行后续操作

            # 提交事务
            current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            print(f"{current_time} - 提交事务")
            connection.commit()

    except Exception as e:
        current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(f"{current_time} - 外部错误: {e}")
        connection.rollback()
        print("Transaction rolled back.")

    finally:
        connection.close()


if __name__ == "__main__":
    connect_to_database()

此外,为了安全地管理数据库凭证,我们使用 get_credentials.py 模块,以存储和获取数据库用户名和密码。



def get_credentials():
    # 替换成你实际的用户名和密码
    credentials = {
        'username': 'root',
        'password': '密码'
    }
    return credentials

结语:保障数据安全与完整性的关键

通过本文,我们深入了解了数据库事务处理的核心概念和重要性。事务(Transaction)、回滚(Rollback)和提交(Commit)这些操作不仅是数据库管理的基础,也是确保数据安全、完整和一致性的关键。

重要性归纳:

  1. 数据完整性:事务确保了即使在出现错误或系统故障的情况下,数据库的完整性也不会受损。
  2. 错误恢复:回滚机制提供了一种有效的错误恢复路径,保护数据免受部分操作失败的影响。
  3. 并发控制:事务的ACID属性在并发环境中维持了数据的一致性和稳定性。

http://www.kler.cn/a/158939.html

相关文章:

  • 几何合理的分片段感知的3D分子生成 FragGen - 评测
  • PlantUML——时序图
  • Vue3 provide 和 inject的使用
  • OpenHarmony-1.启动流程
  • Python知识点精汇!字符串:定义、截取(索引)和其内置函数
  • ubuntu安装 Pycharm
  • 罗技鼠标使用接收器和电脑重新配对
  • 亚信安慧AntDB受邀分享核心业务系统全域数据库替换实践
  • linux 僵尸进程 关闭看不见的进程
  • 【如何用批处理文件实现自动编译Keil工程和C# Visual Studio工程】
  • 用C语言实现单链表
  • 数据结构中处理散列冲突的四种方法
  • 控制台电商项目实现
  • 前端食堂技术周刊第 107 期:技术播客节、Deno Cron、FEDAY、XState v5、Electron 2023 生态系统回顾
  • C++ 12.5作业
  • unaipp引入echarts图表,小程序端能正常显示打包
  • 智能优化算法应用:基于堆优化算法无线传感器网络(WSN)覆盖优化 - 附代码
  • CC++内存管理方式
  • 第18章 C++11标准库(STL)
  • Spring Cloud + Vue前后端分离-第3章 SpringBoot项目技术整合
  • 亚马逊云科技AI创新应用下的托管在AWS上的数据可视化工具—— Amazon QuickSight
  • Hadoop学习笔记(HDP)-Part.07 安装MySQL
  • 生产实践:Redis与Mysql的数据强一致性方案
  • Http中post和get
  • 【华为OD题库-055】金字塔/微商-java
  • C++之枚举与宏定义