Выпуск MySQL подключений в Promise.All - PullRequest
2 голосов
/ 28 октября 2019

Я хочу освободить соединения, заданные пулом MySQL. В цикле «for» соединения освобождаются правильно, но если я использую Promise.All, чтобы сделать это асинхронно, у меня есть некоторые соединения, которые не закрываются. Проблема в том, что через некоторое время я получаю сообщение об ошибке «Слишком много подключений» и не хочу увеличивать число max_connection.

Знаете ли вы, если по какой-либо причине соединения MySQL могут 'быть освобожденным в асинхронной функции?

Вот как я создаю свой пул:

dbPool = mysql2.createPool(Object.assign({}, defaultDBConfig, {
            database: 'my_db,
            waitForConnections: true,
            connectionLimit: 10,
            queueLimit: 0,
            multipleStatements: true,
            dateStrings: true
        }));

Вот функции, которые я использую:

/**
 * @description Allow to do a generic async forEach loop
 * @param {*} array
 * @param {*} callback
 */
async function asyncForEachPromised(array, callback) {
    await Promise.all(array.map(async (items) => {
        await callback(items);
    }));
/**
 * @description ExecuteQuery a query and return an object which contain the result or an error
 * @param {*} dbPool Connection pool
 * @param {*} query Query to executeQuery
 * @param {*} errorMessage Error message to send to the front-end
 * @param {*} elements Array of parameter to send in the query
 */
async function executeQuery(dbPool, query, errorMessage, elements) {

    const status = {
        error: null,
        result: null
    };

    const { error, connection } = await dbPool.getConnection();

    if (error) {
        console.log(error);
        status.error = 'Error when trying to connect to the database.';
    } else {
        try {
            const [rows] = await connection.promise().execute(query, elements);
            connection.release();
            status.result = rows;
        } catch (err) {
            console.log(err);
            status.error = errorMessage;
        }
    }
    return status;
}

Наконец, есть пример кода, который я использую, в этом случае соединения не освобождаются:

const elements = [{prop1: 'a'},{prop1: 'b'}];
await asyncForEachPromised(elements, async (element) => {
    await executeQuery(dbPool, 'my query', 'my error message', [element.prop1]);
});

Но в этом случае они освобождаются правильно:

const elements = [{prop1: 'a'},{prop1: 'b'}];
for (const [,element] of elements.entries()) {
    await executeQuery(dbPool, 'my query', 'my error message', [element.prop1]);
}

1 Ответ

1 голос
/ 28 октября 2019

Вы не можете так делать.

Попробуйте это

Promise.all( arr )
.then( results => //your code with results)
.finally( () => //close connection)
.catch( e => //do what you need )

Но ... вам действительно следует попытаться использовать пул соединений. Что ты используешь ? MySQL узел? https://github.com/mysqljs/mysql#pooling-connections

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...