修復 too many connection 問題
This commit is contained in:
202
lib/smart-connection-pool.ts
Normal file
202
lib/smart-connection-pool.ts
Normal file
@@ -0,0 +1,202 @@
|
||||
// =====================================================
|
||||
// 智能連線池包裝器
|
||||
// =====================================================
|
||||
|
||||
import { db } from './database';
|
||||
import { dbFailover } from './database-failover';
|
||||
import { connectionLifecycleManager } from './connection-lifecycle-manager';
|
||||
|
||||
export class SmartConnectionPool {
|
||||
private static instance: SmartConnectionPool;
|
||||
private connectionCounter = 0;
|
||||
|
||||
private constructor() {}
|
||||
|
||||
public static getInstance(): SmartConnectionPool {
|
||||
if (!SmartConnectionPool.instance) {
|
||||
SmartConnectionPool.instance = new SmartConnectionPool();
|
||||
}
|
||||
return SmartConnectionPool.instance;
|
||||
}
|
||||
|
||||
// 獲取智能連線
|
||||
public async getSmartConnection(metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}): Promise<{
|
||||
connection: any;
|
||||
connectionId: string;
|
||||
release: () => void;
|
||||
}> {
|
||||
const connectionId = `conn_${++this.connectionCounter}_${Date.now()}`;
|
||||
|
||||
try {
|
||||
// 獲取實際連線
|
||||
const connection = await db.getConnection();
|
||||
|
||||
// 註冊到生命週期管理器
|
||||
connectionLifecycleManager.registerConnection(connectionId, connection, metadata);
|
||||
|
||||
// 創建包裝的釋放函數
|
||||
const release = () => {
|
||||
connectionLifecycleManager.releaseConnection(connectionId);
|
||||
};
|
||||
|
||||
console.log(`🔗 獲取智能連線: ${connectionId}`);
|
||||
|
||||
return {
|
||||
connection,
|
||||
connectionId,
|
||||
release
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`❌ 獲取智能連線失敗: ${connectionId}`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 執行智能查詢
|
||||
public async executeQuery<T = any>(
|
||||
sql: string,
|
||||
params?: any[],
|
||||
metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}
|
||||
): Promise<T[]> {
|
||||
const { connection, connectionId, release } = await this.getSmartConnection(metadata);
|
||||
|
||||
try {
|
||||
// 更新連線使用時間
|
||||
connectionLifecycleManager.updateConnectionUsage(connectionId);
|
||||
|
||||
// 執行查詢
|
||||
const [rows] = await connection.execute(sql, params);
|
||||
return rows as T[];
|
||||
} catch (error) {
|
||||
console.error(`❌ 智能查詢失敗: ${connectionId}`, error);
|
||||
throw error;
|
||||
} finally {
|
||||
// 確保釋放連線
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
// 執行智能單一查詢
|
||||
public async executeQueryOne<T = any>(
|
||||
sql: string,
|
||||
params?: any[],
|
||||
metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}
|
||||
): Promise<T | null> {
|
||||
const results = await this.executeQuery<T>(sql, params, metadata);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
}
|
||||
|
||||
// 執行智能插入
|
||||
public async executeInsert(
|
||||
sql: string,
|
||||
params?: any[],
|
||||
metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
const { connection, connectionId, release } = await this.getSmartConnection(metadata);
|
||||
|
||||
try {
|
||||
// 更新連線使用時間
|
||||
connectionLifecycleManager.updateConnectionUsage(connectionId);
|
||||
|
||||
// 執行插入
|
||||
const [result] = await connection.execute(sql, params);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error(`❌ 智能插入失敗: ${connectionId}`, error);
|
||||
throw error;
|
||||
} finally {
|
||||
// 確保釋放連線
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
// 執行智能更新
|
||||
public async executeUpdate(
|
||||
sql: string,
|
||||
params?: any[],
|
||||
metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
const { connection, connectionId, release } = await this.getSmartConnection(metadata);
|
||||
|
||||
try {
|
||||
// 更新連線使用時間
|
||||
connectionLifecycleManager.updateConnectionUsage(connectionId);
|
||||
|
||||
// 執行更新
|
||||
const [result] = await connection.execute(sql, params);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error(`❌ 智能更新失敗: ${connectionId}`, error);
|
||||
throw error;
|
||||
} finally {
|
||||
// 確保釋放連線
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
// 執行智能刪除
|
||||
public async executeDelete(
|
||||
sql: string,
|
||||
params?: any[],
|
||||
metadata?: {
|
||||
userId?: string;
|
||||
sessionId?: string;
|
||||
requestId?: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
const { connection, connectionId, release } = await this.getSmartConnection(metadata);
|
||||
|
||||
try {
|
||||
// 更新連線使用時間
|
||||
connectionLifecycleManager.updateConnectionUsage(connectionId);
|
||||
|
||||
// 執行刪除
|
||||
const [result] = await connection.execute(sql, params);
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error(`❌ 智能刪除失敗: ${connectionId}`, error);
|
||||
throw error;
|
||||
} finally {
|
||||
// 確保釋放連線
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
// 獲取連線統計
|
||||
public getConnectionStats() {
|
||||
return connectionLifecycleManager.getConnectionStats();
|
||||
}
|
||||
|
||||
// 強制清理所有連線
|
||||
public forceCleanup() {
|
||||
connectionLifecycleManager.forceCleanupAll();
|
||||
}
|
||||
|
||||
// 設置清理參數
|
||||
public setCleanupParams(maxIdleTime?: number, maxConnectionAge?: number) {
|
||||
connectionLifecycleManager.setCleanupParams(maxIdleTime, maxConnectionAge);
|
||||
}
|
||||
}
|
||||
|
||||
// 導出單例實例
|
||||
export const smartPool = SmartConnectionPool.getInstance();
|
Reference in New Issue
Block a user