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