modified: backend/src/services/DatabasePoolManager.ts
modified: backend/src/services/SqlExecutor.ts
This commit is contained in:
@@ -52,9 +52,11 @@ class DatabasePoolManager {
|
|||||||
user: dbConfig.username,
|
user: dbConfig.username,
|
||||||
password: dbConfig.password,
|
password: dbConfig.password,
|
||||||
ssl: dbConfig.ssl ? { rejectUnauthorized: false } : false,
|
ssl: dbConfig.ssl ? { rejectUnauthorized: false } : false,
|
||||||
max: 10,
|
max: 20, // Увеличено количество соединений
|
||||||
idleTimeoutMillis: 30000,
|
idleTimeoutMillis: 60000, // 60 секунд
|
||||||
connectionTimeoutMillis: 2000,
|
connectionTimeoutMillis: 10000, // 10 секунд (было 2 секунды)
|
||||||
|
keepAlive: true, // Поддерживать соединения активными
|
||||||
|
keepAliveInitialDelayMillis: 10000, // Начать keepAlive через 10 секунд
|
||||||
});
|
});
|
||||||
|
|
||||||
pool.on('error', (err) => {
|
pool.on('error', (err) => {
|
||||||
|
|||||||
@@ -2,6 +2,33 @@ import { QueryResult } from '../types';
|
|||||||
import { databasePoolManager } from './DatabasePoolManager';
|
import { databasePoolManager } from './DatabasePoolManager';
|
||||||
|
|
||||||
export class SqlExecutor {
|
export class SqlExecutor {
|
||||||
|
private async retryQuery<T>(
|
||||||
|
fn: () => Promise<T>,
|
||||||
|
retries: number = 3,
|
||||||
|
delay: number = 1000
|
||||||
|
): Promise<T> {
|
||||||
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||||
|
try {
|
||||||
|
return await fn();
|
||||||
|
} catch (error: any) {
|
||||||
|
// Retry only on connection-related errors
|
||||||
|
const isConnectionError =
|
||||||
|
error.message?.includes('timeout') ||
|
||||||
|
error.message?.includes('Connection terminated') ||
|
||||||
|
error.message?.includes('ECONNREFUSED') ||
|
||||||
|
error.message?.includes('ETIMEDOUT');
|
||||||
|
|
||||||
|
if (!isConnectionError || attempt === retries) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn(`Query attempt ${attempt} failed, retrying in ${delay}ms...`);
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delay));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Max retries exceeded');
|
||||||
|
}
|
||||||
|
|
||||||
async executeQuery(
|
async executeQuery(
|
||||||
databaseId: string,
|
databaseId: string,
|
||||||
sqlQuery: string,
|
sqlQuery: string,
|
||||||
@@ -19,7 +46,11 @@ export class SqlExecutor {
|
|||||||
// Security: Prevent multiple statements and dangerous commands
|
// Security: Prevent multiple statements and dangerous commands
|
||||||
this.validateQuery(sqlQuery);
|
this.validateQuery(sqlQuery);
|
||||||
|
|
||||||
const result = await pool.query(sqlQuery, params);
|
// Execute with retry mechanism
|
||||||
|
const result = await this.retryQuery(async () => {
|
||||||
|
return await pool.query(sqlQuery, params);
|
||||||
|
}, 3, 500); // 3 попытки с задержкой 500ms
|
||||||
|
|
||||||
const executionTime = Date.now() - startTime;
|
const executionTime = Date.now() - startTime;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user