Процесс node останавливается в ожидании данных от сервера БД

Рейтинг: 0Ответов: 1Опубликовано: 02.03.2023

Есть несколько запросов к БД, которые выполняются долго(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

Ответы

▲ 0Принят

Не знаю, почему не работал пример выше. Так и не раскопал

Переписал 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, перестал замирать в ожидании данных.