Процесс node останавливается в ожидании данных от сервера БД
Есть несколько запросов к БД, которые выполняются долго(20-40 сек).
Запросы: Вызов хранимой процедуры, где идет сборка SQL запроса и в OUT переменную возвращается REF_CURSOR.
В упрощенном виде это выглядит так:
PROCEDURE selectSomeDate(res out sys_refcursor)
IS
BEGIN
open res for 'select x from dual';
END;
Для взаимодействия с СУБД Oracle используется библиотека oracledb
Есть вот такой незатейливый код(в очень упрощенном формате)
async function getConnect() {
conn = await oradb.getConnection(); // Получили соединение из пула
const result = await conn.execute(sqltext, binds, opts);
return result;
}
Есть функция, которая извлекает данные из курсора. sqlStatement это return из фукнции getConnect
async function getData(sqlStatement) {
const connect = sqlStatement.conn; // Получаем коннект
const cursor = sqlStatement.result.outBinds.result; // Получаем ссылку на открыты курсор
// Вот тут происходит выборка данных из курсора
const res = await cursor.getRows(); // <- Вот тут все останавливается
await cursor.close().catch(e => { // Закрываем курсор
logger.error(msg(`Ошибка закрытия курсора ${e}`, printStackTrace(e)));
});
await connect.close().catch(e => { // Закрываем соединение
logger.error(msg(`Ошибка закрытия соединения ${e}`, printStackTrace(e)));
});
return res;
}
Установлена переменная среды UV_THREADPOOL_SIZE=100
Я не могу понять, почему при ожидании данных от сервера(читать как ожидание выполнения SQL запроса), процесс nodejs зависает.
Везде в доках и мануалах написано, делайте так и будет вам счастье. Никаких "уточнений" по ожиданию данных, нет предупреждений о том что может быть заблокировано что то в node.
Если запросы отправить пачкой, все остановится тут же. Если запрос отправить 1, то процесс остановится через N секунд(Видимо что то где то забивает - только вот что это может быть...)
После получения ответа от БД, все продолжает рабоать успешно и шустро. Во время "зависания" node не отвечает ни на какие сетевые запросы, так же прекращается вывод в консоль.
Возможно кто то сталкивался с таким? В какую сторону копать и что смотреть?
Окружение
nodejs 14.17, БД Oracle 19, Oracle client 12.2, OS: Rhel 7 и Windows 10
Ответы (1 шт):
Не знаю, почему не работал пример выше. Так и не раскопал
Переписал SQL процедуру и скрипт выборки данных на стороне node js и заработало
Меняем процедуру с помощью пакета DBMS_SQL(Убираем из параметров процедуры out переменную res и объявляем ее в самой процедуре):
PROCEDURE selectSomeDate()
IS
res sys_refcursor;
BEGIN
open res for 'select x from dual'; -- It takes several minutes to complete
DBMS_SQL.return_result(res);
END;
В node js меняем получение данных с outbind переменной на implicitResults:
async function getData(sqlStatement) {
const connect = sqlStatement.conn;
const cursor = await sqlStatement.implicitResults[0];
// Читаем данные
const res = await cursor.getRows(); // <- Теперь здесь процесс не замирает
await cursor.close().catch(e => {
logger.error(msg(`Ошибка закрытия курсора ${e}`, printStackTrace(e)));
});
await connect.close().catch(e => {
logger.error(msg(`Ошибка закрытия соединения ${e}`, printStackTrace(e)));
});
return res;
}
После этого, процесс node js, перестал замирать в ожидании данных.