如何使用 Python 处理数据库事务?

news2024/12/20 10:22:07

在Python中处理数据库事务,我们通常会使用数据库连接库提供的上下文管理器或者显式地调用开始、提交和回滚事务的方法。

以SQLite为例,我们可以使用sqlite3模块来演示如何处理事务。

基本概念

数据库事务是一系列操作的集合,这些操作要么全部成功执行,要么全部不执行。事务具有四个基本特性,通常被称为ACID属性:

  • 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
  • 一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。
  • 隔离性(Isolation):事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰。
  • 持久性(Durability):一个事务一旦被提交,它对数据库中数据的改变就是永久性的。
使用Python的sqlite3模块处理事务

下面是一个使用sqlite3模块处理事务的基本示例:

import sqlite3

# 连接到SQLite数据库
# 数据库文件是test.db
# 如果文件不存在,会自动在当前目录创建一个
conn = sqlite3.connect('test.db')

# 创建一个Cursor对象并执行SQL语句
cursor = conn.cursor()

# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    age INTEGER
)
''')

# 开始事务
conn.execute('BEGIN TRANSACTION')

try:
    # 插入数据
    cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Alice', 25))
    cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Bob', 30))
    
    # 提交事务
    conn.commit()
    print("数据插入成功,事务已提交。")
except sqlite3.Error as e:
    # 发生错误时回滚事务
    conn.rollback()
    print(f"发生错误,事务已回滚: {e}")
finally:
    # 关闭Cursor和连接
    cursor.close()
    conn.close()
使用上下文管理器处理事务

Python的上下文管理器可以帮助我们更简洁地处理事务,确保即使发生异常也能正确回滚事务:

import sqlite3

# 创建一个上下文管理器来处理事务
class Transaction:
    def __init__(self, connection):
        self.connection = connection

    def __enter__(self):
        self.connection.execute('BEGIN TRANSACTION')
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type is None:
            self.connection.commit()
            print("事务已提交。")
        else:
            self.connection.rollback()
            print(f"发生错误,事务已回滚: {exc_val}")
        self.connection.close()

# 使用上下文管理器
with sqlite3.connect('test.db') as conn:
    with Transaction(conn) as tx:
        cursor = tx.cursor()
        cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Charlie', 35))
        cursor.execute("INSERT INTO users (name, age) VALUES (?, ?)", ('Diana', 40))
        # 如果在这里抛出异常,事务将会回滚
        # raise ValueError("模拟错误")
日常开发中的合理化使用建议
  1. 尽量保持事务简短:长时间的事务会增加锁冲突的可能性,降低数据库性能。
  2. 使用合适的隔离级别:根据应用的需求选择合适的隔离级别,以平衡数据一致性和并发性能。
  3. 避免在事务中执行耗时操作:如网络请求或大量计算,这些操作会延长事务的执行时间。
  4. 异常处理:确保在发生异常时能够正确回滚事务,避免数据不一致。
  5. 使用批量操作:批量插入、更新或删除可以减少事务的数量,提高效率。
实际开发过程中需要注意的点
  1. 资源管理:确保数据库连接和游标在使用后被正确关闭,避免资源泄露。
  2. 并发控制:在高并发环境下,合理使用锁和事务隔离级别,防止死锁和竞态条件。
  3. 性能监控:监控数据库性能,及时发现并解决慢查询和锁等待问题。
  4. 数据验证:在执行事务前,对数据进行验证,确保数据的合法性和完整性。
  5. 日志记录:记录事务的开始、提交和回滚操作,便于问题追踪和审计。

在实际开发中,我们可能还会使用ORM(对象关系映射)框架,如SQLAlchemy,它提供了更高级的事务管理功能。以下是使用SQLAlchemy处理事务的一个简单示例:

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

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

engine = create_engine('sqlite:///test.db')
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)

# 使用Session对象处理事务
with Session() as session:
    try:
        new_user1 = User(name='Eve', age=45)
        new_user2 = User(name='Frank', age=50)
        session.add(new_user1)
        session.add(new_user2)
        session.commit()  # 提交事务
        print("数据插入成功,事务已提交。")
    except Exception as e:
        session.rollback()  # 发生错误时回滚事务
        print(f"发生错误,事务已回滚: {e}")

使用SQLAlchemy等ORM框架可以让我们以更面向对象的方式处理数据库事务,同时框架内部已经处理了很多底层的细节,使得代码更加简洁和易于维护。

合理地使用数据库事务对于保证数据的一致性和完整性至关重要。在实际开发中,我们需要根据具体的业务场景和性能要求,选择合适的事务处理策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2262648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Ubuntu】设置静态Ip

查看网卡 ifconfig | grep -A 5 -B 2 192 修改配置文件 sudo vim /etc/netplan/00-installer-config.yamlnetwork:ethernets:enp0s3:dhcp4: noaddresses:- 192.168.1.100/24gateway4: 192.168.1.1nameservers:addresses:- 8.8.8.8- 8.8.4.4​​​​​

演员念真主演电视剧《依依向北风》获奖

2024年12月17日,南京广播电视集团和江苏12家城市台的领导、嘉宾,全国其他省市电视台嘉宾,影视公司代表、项目主创团队代表等,相聚南京国际青年会议酒店,举行江苏城市联合公司“城市之星”项目资源推介会暨2024年度“城…

Word使用分隔符实现页面部分分栏

文章目录 Word使用分隔符实现页面部分分栏分隔符使用页面设置 Word使用分隔符实现页面部分分栏 分隔符使用 word中的分隔符: 前面不分栏,后面分栏(或前面分栏,后面不分栏),只需要在分隔位置处插入分隔符:“连续”即…

Sensapex 微纳米显微平台:高精度、低漂移、模块化的科研引擎

Sensapex微纳米显微平台以其卓越的技术性能,成为科研领域的重要工具。其高精度定位技术确保了实验结果的可靠性,低漂移设计适应了长时间复杂实验的需求。模块化设计为用户提供了灵活性,可根据不同实验需求自由组合。Sensapex微纳米显微平台广…

江协科技 OLED库 OLED_Print( )函数自动换行

void OLED_Printf(int16_t X, int16_t Y, uint8_t FontSize, char *format, ...) {char String[256]; //定义字符数组va_list arg; //定义可变参数列表数据类型的变量argva_start(arg, format); //从format开始,接收参数列表到arg变量vsprintf(Strin…

探索 Seaborn Palette 的奥秘:为数据可视化增色添彩

一、引言 在数据科学的世界里,视觉传达是不可或缺的一环。一个好的数据可视化不仅能传递信息,还能引发共鸣。Seaborn 是 Python 中一款广受欢迎的可视化库,而它的调色板(palette)功能,则为我们提供了调配绚…

领域驱动设计的学习分享

DDD 是什么 领域驱动设计(Domain Driven Design) 是一种从系统分析到软件建模的一套方法论。以领域为核心驱动力的设计体系。 为什么使用 面向对象设计,数据行为绑定,告别贫血模型优先考虑领域模型,而不是切割数据和行为准确传达业务规则…

Three.js推荐-可以和Three.js结合的动画库

在 Three.js 中,3D 模型、相机、光照等对象的变换(如位置、旋转、缩放)通常需要通过动画进行控制,以实现更加生动和富有表现力的效果。然而,Three.js 本身并没有内置的强大动画管理系统,尽管可以通过关键帧…

vue+springboot+cas配置及cookie传递问题

cookie的注意事项 前边的文章已经介绍过cookie的基本信息,这里再次说明一点:cookie是无法进行跨域传递的,很多时候cookie无法设置和传递都是因为跨域问题,ip/端口不一致。 主要就是:被设置cookie和要传递cookie的地址…

Mac升级macOS 15 Sequoia后,无法ssh连接本地虚拟机

现象 macOS 15后,无法ssh连接本地启动的虚拟机,提示错误: No route to host,也ping不通。包括UTM、Parallels Desktop这两个虚拟机软件。之前都是没问题的,通过一些简单排查,目前没发现什么问题。 在虚拟…

使用 NVIDIA DALI 计算视频的光流

引言 光流(Optical Flow)是计算机视觉中的一种技术,主要用于估计视频中连续帧之间的运动信息。它通过分析像素在时间维度上的移动来预测运动场,广泛应用于目标跟踪、动作识别、视频稳定等领域。 光流的计算传统上依赖 CPU 或 GP…

c语言----顺序结构

顺序结构的基本概念 定义:顺序结构是C语言程序中最基本的结构,它按照语句的先后顺序依次执行。就像我们日常做事一样,一步一步地按照顺序来完成任务。在C语言程序中,从程序的第一条语句开始,逐句向下执行,…

基于base32的兑换码算法(思路)

base32编码指的是基于32个可打印字符对任意字节数据进行编码:大写字母A-Z以及数字2-7。 兑换码要求:长度为10个字符 如果将这32个字符依次放到一个base数组中,那么最大的下标就是31。我们将要编码的任意字节数据按照五个bit为一组进行划分,…

python学opencv|读取图像(十六)修改HSV图像HSV值

【1】引言 前序学习进程中,我们已经掌握了对HSV通道和BGR通道的拆分和合并,并通过自由组合的形式,获得了和初始图像完全不一样的新图像,相关文章可以参考下述链接: python学opencv|读取图像(十四&#xf…

用QT制作的倒计时软件

一、pro代码 RC_ICONS countdown.ico 二、mainwindow.cpp代码 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QDateTime> #include <QMessageBox> #include <QSettings>MainWindow::MainWindow(QWidget *parent): QM…

VScode MAC按任意键关闭终端 想要访问桌面文件

说明 最近配置MAC上CPP的运行环境&#xff0c;在安装必要的CPP插件后&#xff0c;配置launch和task等json文件后&#xff0c;点击运行三角形&#xff0c;每次都会跳出main想要访问桌面上的文件。并且输出也是在调试控制台&#xff0c;非常逆天。 尝试 尝试1:尽管我尝试将ta…

【一本通】线段

【一本通】线段 C语言代码Java代码C代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 数轴上有 n条线段&#xff0c;选取其中 k条线段使得这 k条线段两两没有重合部分&#xff0c;问最大的k为多少? 输入 输入文件segment.in的第一行为…

学习日志024--opencv中处理轮廓的函数

目录 前言​​​​​​​ 一、 梯度处理的sobel算子函数 功能 参数 返回值 代码演示 二、梯度处理拉普拉斯算子 功能 参数 返回值 代码演示 三、Canny算子 功能 参数 返回值 代码演示 四、findContours函数与drawContours函数 功能 参数 返回值 代码演示 …

关于分页的样式问题

在最近写网页的时候遇到了一个关于样式的问题&#xff0c;今天我来跟大家来说一下。像是分页中的颜色效果&#xff0c;斑马纹颜色要注意颜色不要过于深。 这种的颜色就有一点深看着很不舒服&#xff0c;应将当前的颜色改为淡一点的&#xff0c;也可以利用rgba调整透明度&#x…

机器学习周报(12.9-12.15)

文章目录 摘要Abstract 1 Swin Transformer1.1 输入1.2 Patch Partition1.3 Linear Embedding1.4 Patch Merging1.5 Swin Transformer Block1.6 代码总结 摘要 本篇博客介绍了采用类似于卷积核的移动窗口进行图像特征提取的Swin Transformer网络模型&#xff0c;这是一种基于T…