sqlite3 事务

sqlite3 事务

sqlite3 事务

1. 什么是事务

在数据库管理系统中,事务(Transaction)是指作为一个逻辑单位的一组数据库操作,这些操作要么都执行,要么都不执行。事务可以保证数据库的一致性和完整性。

事务具有以下四个特性(ACID):

  • 原子性(Atomicity):一个事务中的所有操作要么全部成功,要么全部失败,不允许部分操作成功。
  • 一致性(Consistency):事务的执行保持数据库的一致状态,从一个一致的状态转移到另一个一致的状态。
  • 隔离性(Isolation):并发执行的事务之间是相互隔离的,一个事务看不到另一个事务的中间状态。事务之间的执行是串行化的。
  • 持久性(Durability):一旦事务提交,其所做的修改就会永久保存到数据库,即使发生系统故障也不会丢失。

2. SQLite3 事务

SQLite3 是一种轻量级的嵌入式关系型数据库,支持事务功能。在 SQLite3 中,事务是通过对 SQL 语句进行操作来实现的。

SQLite3 使用以下语句来控制事务:

  • BEGIN:开始一个事务。
  • COMMIT:提交一个事务,使得对数据库的修改永久生效。
  • ROLLBACK:回滚一个事务,撤销对数据库的修改。

SQLite3 还支持自动提交事务的功能。当没有显式地使用 BEGIN 和 COMMIT 语句时,每个 SQL 语句都会被视为一个事务,并自动提交。

3. SQLite3 事务的用法

3.1 手动控制事务

在 SQLite3 中,可以使用 BEGIN 和 COMMIT 语句手动控制事务的开始和提交。下面是一个示例代码:

import sqlite3

# 连接到 SQLite 数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()

# 创建一个表格
c.execute('''CREATE TABLE IF NOT EXISTS books
    (id INT PRIMARY KEY,
    title TEXT,
    author TEXT)''')

# 开始事务
c.execute("BEGIN")

# 插入数据
c.execute("INSERT INTO books (id, title, author) VALUES (1, 'Book 1', 'Author 1')")
c.execute("INSERT INTO books (id, title, author) VALUES (2, 'Book 2', 'Author 2')")

# 提交事务
c.execute("COMMIT")

# 关闭数据库连接
conn.close()

上述代码中,首先使用 BEGIN 语句开始事务,然后执行插入操作,最后使用 COMMIT 语句提交事务。如果在插入操作之后发生错误,可以使用 ROLLBACK 语句回滚事务,撤销对数据库的修改。

3.2 自动提交事务

SQLite3 默认情况下会自动提交每个 SQL 语句,因此不需要显式地使用 BEGINCOMMIT 语句。下面是一个示例代码:

import sqlite3

# 连接到 SQLite 数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()

# 创建一个表格
c.execute('''CREATE TABLE IF NOT EXISTS books
    (id INT PRIMARY KEY,
    title TEXT,
    author TEXT)''')

# 插入数据,这里不需要使用 BEGIN 和 COMMIT 语句

c.execute("INSERT INTO books (id, title, author) VALUES (1, 'Book 1', 'Author 1')")
c.execute("INSERT INTO books (id, title, author) VALUES (2, 'Book 2', 'Author 2')")

# 关闭数据库连接
conn.close()

上述代码中,不需要显式地使用 BEGINCOMMIT 语句,每个插入语句都会自动成为一个事务,并自动提交。

3.3 回滚事务

在发生错误或其他异常情况时,可以使用 ROLLBACK 语句回滚事务,撤销对数据库的修改。下面是一个示例代码:

import sqlite3

# 连接到 SQLite 数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()

# 创建一个表格
c.execute('''CREATE TABLE IF NOT EXISTS books
    (id INT PRIMARY KEY,
    title TEXT,
    author TEXT)''')

try:
    # 开始事务
    c.execute("BEGIN")

    # 插入数据
    c.execute("INSERT INTO books (id, title, author) VALUES (1, 'Book 1', 'Author 1')")
    c.execute("INSERT INTO books (id, title, author) VALUES (2, 'Book 2', 'Author 2')")

    # 抛出异常
    raise Exception("Simulated exception")

    # 提交事务
    c.execute("COMMIT")
except:
    # 回滚事务
    c.execute("ROLLBACK")

# 关闭数据库连接
conn.close()

上述代码中,抛出了一个异常,触发了回滚操作。在回滚操作后,数据库中的修改将被撤销。

4. SQLite3 事务的性能优化

在使用 SQLite3 事务时,以下技巧可以帮助提高性能:

4.1 批量操作

将多个操作合并为一个事务,可以减少事务的开销,提高性能。以下是一个示例代码:

import sqlite3

# 连接到 SQLite 数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()

# 创建一个表格
c.execute('''CREATE TABLE IF NOT EXISTS books
    (id INT PRIMARY KEY,
    title TEXT,
    author TEXT)''')

# 开始事务
c.execute("BEGIN")

# 批量插入数据
books = [(3, 'Book 3', 'Author 3'), (4, 'Book 4', 'Author 4')]
c.executemany("INSERT INTO books (id, title, author) VALUES (?, ?, ?)", books)

# 提交事务
c.execute("COMMIT")

# 关闭数据库连接
conn.close()

上述代码中,使用 executemany 方法一次性插入多条数据,减少了事务的开销。

4.2 禁用日志

在 SQLite3 中,默认会将每个事务的操作记录在内存中的日志文件中。禁用日志文件可以进一步提高性能。以下是一个示例代码:

import sqlite3

# 连接到 SQLite 数据库
conn = sqlite3.connect('example.db')
c = conn.cursor()

# 禁用日志
c.execute("PRAGMA journal_mode = OFF")

# 创建一个表格
c.execute('''CREATE TABLE IF NOT EXISTS books
    (id INT PRIMARY KEY,
    title TEXT,
    author TEXT)''')

# 开始事务
c.execute("BEGIN")

# 插入数据
c.execute("INSERT INTO books (id, title, author) VALUES (1, 'Book 1', 'Author 1')")
c.execute("INSERT INTO books (id, title, author) VALUES (2, 'Book 2', 'Author 2')")

# 提交事务
c.execute("COMMIT")

# 关闭数据库连接
conn.close()

上述代码中,通过使用 PRAGMA journal_mode = OFF 语句禁用了日志文件,从而提高了性能。在高负载场景下,禁用日志可以显著减少磁盘操作,加快事务处理速度。

5. 总结

本文详细介绍了 SQLite3 中事务的概念和用法。通过手动控制事务的开始和提交,或者使用自动提交事务的功能,可以确保数据库操作的原子性、一致性、隔离性和持久性。另外,通过批量操作和禁用日志等性能优化技巧,还可以提高事务处理的效率。SQLite3 提供了简单而强大的事务支持,使得在开发数据库应用程序时更加灵活和可靠。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程