【python下用sqlite3, 多线程下报错,原因和解决 】

在python下用sqlite3, 多线程 在UPDATE 或者INSERT的时候, 会报错

sqlite3.OperationalError: cannot commit - no transaction is active

1. 原因

多线程写冲突

  • 非原子写操作:如果多个线程同时执行非原子写操作,可能会导致数据覆盖或不一致。

2. 解决方案

使用锁

使用锁来确保同一时间只有一个线程可以执行写操作。

go 复制代码
import sqlite3
import threading

lock = threading.Lock()

def worker(conn, thread_id):
    with lock:
        cursor = conn.cursor()
        cursor.execute("INSERT INTO test (id, value) VALUES (?, ?)", (thread_id, f"value_{thread_id}"))
        conn.commit()
        cursor.close()

def main():
    conn = sqlite3.connect('example.db', check_same_thread=False)
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)")
    conn.commit()
    cursor.close()

    threads = []
    for i in range(5):
        thread = threading.Thread(target=worker, args=(conn, i))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    conn.close()

if __name__ == "__main__":
    main()

使用事务

显式事务管理:在每个线程中显式地开始和提交事务,确保事务的原子性和一致性。

go 复制代码
import sqlite3
import threading

def worker(conn, thread_id):
    cursor = conn.cursor()
    cursor.execute("BEGIN")
    cursor.execute("INSERT INTO test (id, value) VALUES (?, ?)", (thread_id, f"value_{thread_id}"))
    conn.commit()
    cursor.close()

def main():
    conn = sqlite3.connect('example.db', check_same_thread=False)
    cursor = conn.cursor()
    cursor.execute("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)")
    conn.commit()
    cursor.close()

    threads = []
    for i in range(5):
        thread = threading.Thread(target=worker, args=(conn, i))
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    conn.close()

if __name__ == "__main__":
    main()
相关推荐
qq_206901391 天前
golang如何实现跳表Skip List_golang跳表Skip List实现总结
jvm·数据库·python
APIshop1 天前
Python 爬虫获取闲鱼商品详情 API 接口实战指南
开发语言·爬虫·python
weixin_580614001 天前
如何设置密码复杂度策略以约束MongoDB用户的密码强度
jvm·数据库·python
Greyson11 天前
HTML怎么标注字数限制提示_HTML实时字数统计占位【详解】
jvm·数据库·python
qq_372906931 天前
golang如何在Gin中实现路由分组_golang Gin路由分组实现方法
jvm·数据库·python
观无1 天前
FastAPI + SQLite 原生无主键表 完整增删改查
数据库·sqlite·fastapi
qq_342295821 天前
如何备份大量小表组成的数据库_并行导出与多文件并发写入.txt
jvm·数据库·python
justjinji1 天前
MySQL存储过程中如何防止SQL注入_使用参数化查询规范
jvm·数据库·python
qq_206901391 天前
mysql索引排序规则设置方法_mysqlCollation对索引影响
jvm·数据库·python
HHHHH1010HHHHH1 天前
如何快速重置SQL表中的自增ID_使用TRUNCATE与重置命令
jvm·数据库·python