Files
2025-09-19 16:47:15 +08:00

90 lines
3.3 KiB
Python

import sqlite3
import threading
# 数据库文件路径
db_path = 'car_info.db'
# 使用线程本地存储来保存每个线程的连接
_thread_local = threading.local()
# 全局连接引用计数
global_ref_count = 0
def get_db_connection():
"""获取数据库连接(线程本地存储模式)
使用线程本地存储确保每个线程都有自己的数据库连接,解决SQLite多线程问题
Returns:
sqlite3.Connection: 当前线程的数据库连接对象
"""
global global_ref_count
# 检查当前线程是否已有连接
if not hasattr(_thread_local, 'connection') or _thread_local.connection is None:
try:
# 为当前线程创建新连接
_thread_local.connection = sqlite3.connect(db_path)
# 设置行工厂,使查询结果以字典形式返回
_thread_local.connection.row_factory = sqlite3.Row
# 增加全局引用计数
global_ref_count += 1
except sqlite3.Error as e:
print(f"数据库连接失败: {e}")
raise
return _thread_local.connection
def close_db_connection(conn=None):
"""关闭数据库连接(线程本地存储模式)
1. 如果传入了连接对象,直接关闭它
2. 如果没有传入连接对象,但当前线程有连接,则关闭当前线程的连接
Args:
conn (sqlite3.Connection): 需要关闭的数据库连接对象(可选)
"""
global global_ref_count
# 如果指定了连接对象,直接关闭
if conn:
try:
conn.close()
# 如果关闭的是当前线程的连接,更新线程本地存储
if hasattr(_thread_local, 'connection') and _thread_local.connection == conn:
_thread_local.connection = None
global_ref_count = max(0, global_ref_count - 1)
except sqlite3.Error as e:
print(f"关闭数据库连接时出错: {e}")
else:
# 如果没有指定连接对象,尝试关闭当前线程的连接
if hasattr(_thread_local, 'connection') and _thread_local.connection is not None:
try:
_thread_local.connection.close()
_thread_local.connection = None
global_ref_count = max(0, global_ref_count - 1)
except sqlite3.Error as e:
print(f"关闭当前线程的数据库连接时出错: {e}")
def close_global_connection():
"""全局连接清理函数(线程本地存储模式)
在应用程序关闭时调用此函数,它会:
1. 关闭当前线程的数据库连接(如果有)
2. 重置全局引用计数
注意:由于使用了线程本地存储,无法直接关闭其他线程的连接。
每个线程应该在结束前自行关闭其连接。
"""
global global_ref_count
# 关闭当前线程的连接(如果有)
if hasattr(_thread_local, 'connection') and _thread_local.connection is not None:
try:
_thread_local.connection.close()
_thread_local.connection = None
except sqlite3.Error as e:
print(f"关闭当前线程的数据库连接时出错: {e}")
# 重置全局引用计数
global_ref_count = 0