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

SQLite的入门级项目学习记录(二)

再补充一些基础知识:

并行操作的问题

    1、可以多游标同时运行

      SQLite,对于同一个连接sqlite3.connect(db_file),可以同时创建多个游标,每个游标都是独立的,可以执行各自的SQL命令序列。

import sqlite3

# 创建数据库连接
conn = sqlite3.connect('example.db')

# 创建第一个游标
cursor1 = conn.cursor()
cursor1.execute("SELECT * FROM table_1")

# 创建第二个游标
cursor2 = conn.cursor()
cursor2.execute("SELECT * FROM table_2")

# 获取第一个游标的结果
results1 = cursor1.fetchall()
for row in results1:
    print(row)

# 获取第二个游标的结果
results2 = cursor2.fetchall()
for row in results2:
    print(row)

# 关闭游标和连接
cursor1.close()
cursor2.close()
conn.close()

        在这个例子中,cursor1和cursor2是两个独立的游标,它们可以同时执行不同的查询任务。但是,所有的游标操作都会通过同一个数据库连接conn来与数据库进行交互。
        需要注意的是,尽管可以创建多个游标,但SQLite数据库是单线程的,这意味着在任何给定的时间点上,只有一个游标的操作可以被执行。如果需要并发执行多个数据库操作,可能需要考虑使用其他的数据库系统或者使用多线程/多进程的方式来处理。

2、关于多游标多线程访问同一个数据库

        SQLite 支持多线程访问数据库,但是它并不是为高并发设计的。
        SQLite 使用文件锁来同步对数据库文件的访问,这意味着多个线程可以打开数据库连接并对数据库进行读操作,但是在任何给定时间点上,只允许一个线程进行写操作
        在多线程环境中使用 SQLite 时,应该注意以下几点:
        读写锁:SQLite 使用读写锁(Read-Write Lock)来控制对数据库的并发访问。多个线程可以同时获得读锁,但是当有线程持有写锁时,其他线程无法获得读锁或写锁。
        事务:在多线程环境中,每个线程应该使用自己的数据库连接,并且在进行写操作时应该使用事务来确保数据的一致性。
        连接池:由于 SQLite 的并发性能有限,使用连接池可以提高性能,因为连接可以被重用,而不是为每个线程创建一个新的连接。
        线程安全:确保你的应用程序代码是线程安全的,特别是在多线程环境下共享资源时。
        性能考虑:由于 SQLite 的设计限制,它在高并发写操作的场景下可能表现不佳。如果你的应用程序需要处理大量的并发写操作,可能需要考虑使用更适合高并发的数据库系统,如 PostgreSQL 或 MySQL。

import sqlite3
import threading


# 定义工作函数
def worker(conn):
    cursor = conn.cursor()
    cursor.execute("INSERT INTO some_table (column1, column2) VALUES (?, ?)", ('value1', 'value2'))
    conn.commit()
    cursor.close()


# 创建数据库连接
conn = sqlite3.connect('example.db', check_same_thread=False)

# 创建表
conn.execute("CREATE TABLE IF NOT EXISTS some_table (column1 TEXT, column2 TEXT)")

# 创建多个线程
threads = []
for i in range(10):
    t = threading.Thread(target=worker, args=(conn,))
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

# 关闭连接
conn.close()

3、关于SQLite 的锁机制

        SQLite 使用文件锁来处理多个线程同时对同一条记录执行写操作的情况。当一个线程尝试对一条记录执行写操作时,SQLite 会对这条记录加写锁。如果此时有其他线程已经持有该记录的写锁或者正在等待写锁,那么尝试获取写锁的线程将会被阻塞,直到前面的写操作完成并且锁被释放。
SQLite 的锁机制如下
共享锁(Shared Locks):允许多个线程同时读取同一条记录,但不允许写入。
互斥锁(Reserved Locks):表示一个线程打算写入一条记录,但尚未开始写入。在这个状态下,其他线程仍然可以获得共享锁进行读取,但不能获得写锁。
未决锁(Pending Locks):当一个线程试图获取写锁,但发现已经有其他线程持有共享锁或保留锁时,它会进入未决状态。在这个状态下,线程会等待直到可以获取写锁。
独占锁(Exclusive Locks):当一个线程获得写锁时,其他线程无法获得任何类型的锁,直到写锁被释放。
        如果多个线程同时尝试写入同一条记录,SQLite 会按照它们尝试获取锁的顺序来处理。一旦一个线程获得了写锁,其他线程就必须等待,直到写锁被释放。这确保了即使在多线程环境下,SQLite 也能保持数据的一致性和完整性。
        然而,由于 SQLite 的这种锁机制,它在高并发写操作的场景下可能表现不佳。如果应用程序需要处理大量的并发写操作,可能需要考虑使用更适合高并发的数据库系统,如 PostgreSQL 或 MySQL。


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

相关文章:

  • 《Python Web 抓取实战:豆瓣电影 Top 250 数据抓取与分析》
  • 用友U8-Cloud uapbd.refdef.query sql注入漏洞复现
  • 4-6-2.C# 数据容器 - ArrayList 扩展(ArrayList 注意事项、ArrayList 存储对象的特性、ArrayList 与数组的转换)
  • [JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决
  • vue面试题7|[2024-11-14]
  • ARM架构中断与异常向量表机制解析
  • 汽车租赁系统1.0版本
  • Linux——进程状态
  • 【React Native】第三方组件
  • 前端层面----监控与埋点
  • EasyExcel拿表头(二级表头)爬坑,invokeHeadMap方法
  • 记录一下,Vcenter清理/storage/archive空间
  • kafka 之 本地部署单机版
  • spring项目期间的学习9/11
  • 《论企业集成平台的技术与应用》写作框架,软考高级系统架构设计师
  • 数据库系统 第58节 数据库审计
  • 创意无限:五款AI绘画应用,让艺术创作更简单
  • Java基础 --- 多线程JUC,以及一些常用的设计模式总结
  • 前端form表单+ifarme方式实现大文件下载
  • OpenAI 刚刚推出 o1 大模型!!突破LLM极限
  • 医疗行业怎么节约和管理能源
  • Leetcode 每日一题:Longest Increasing Path in a Matrix
  • Python安装:Mac 使用brew 安装Python2 和 Python3
  • 古文字定位系统源码分享
  • [项目实战]EOS多节点部署
  • 深入解析 org.apache.maven.plugins