90 lines
3.3 KiB
Python
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 |