亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索
首頁 > web前端 > js教程 > 正文

解決 node-oracledb 6.0 Thin 模式腳本結(jié)束延遲問題

碧海醫(yī)心
發(fā)布: 2025-10-04 11:05:01
原創(chuàng)
928人瀏覽過

解決 node-oracledb 6.0 thin 模式腳本結(jié)束延遲問題

node-oracledb 6.0 Thin 模式下,若不顯式關(guān)閉數(shù)據(jù)庫連接,Node.js 腳本在執(zhí)行完畢后會出現(xiàn)數(shù)秒的延遲才終止。這是因為 Thin 模式直接管理網(wǎng)絡(luò)套接字,這些套接字會保持 Node.js 事件循環(huán)活躍,直到被垃圾回收器處理。為避免此延遲,務(wù)必通過 connection.close() 明確釋放連接資源,確保腳本即時終止并有效管理資源。本文將深入探討這一現(xiàn)象的原因,并通過示例代碼展示如何正確處理,以確保 Node.js 應(yīng)用的預(yù)期行為和高效資源管理。

現(xiàn)象:腳本執(zhí)行后的意外停頓

在使用 node-oracledb 6.0 的默認 Thin 模式開發(fā) Node.js 應(yīng)用時,開發(fā)者可能會觀察到一個令人困惑的現(xiàn)象:即使所有數(shù)據(jù)庫操作 seemingly 完成,腳本也不會立即終止,而是會停頓數(shù)秒后才退出。這種延遲尤其在使用 time 命令衡量腳本執(zhí)行時間時表現(xiàn)得非常明顯。

考慮以下 Node.js 腳本,它連接到 Oracle 數(shù)據(jù)庫并執(zhí)行一個簡單的查詢,但有意不關(guān)閉數(shù)據(jù)庫連接:

const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js'); // 包含數(shù)據(jù)庫連接配置

async function runApp() {
  let connection;
  try {
    connection = await oracledb.getConnection(dbConfig);
    const result = await connection.execute(`select * from dual`);
    console.dir(result.rows, { depth: null });
    console.log('未關(guān)閉連接');
    // 注意:此處 connection.close() 被注釋掉
  } catch (err) {
    console.error(err);
  } finally {
    // 即使在 finally 塊中,如果 connection.close() 被注釋,問題依然存在
    // if (connection) {
    //   try {
    //     await connection.close();
    //     console.log('連接已關(guān)閉');
    //   } catch (err) {
    //     console.error(err);
    //   }
    // }
  }
}

runApp();
登錄后復(fù)制

當(dāng)我們在 Linux 環(huán)境下使用 time 命令運行上述腳本時,會發(fā)現(xiàn)明顯的延遲:

$ time node t.js
[ [ 'X' ] ]
未關(guān)閉連接

real    0m8.187s  # 實際執(zhí)行時間長達8秒多
user    0m0.092s
sys 0m0.017s
登錄后復(fù)制

然而,如果我們將 await connection.close() 取消注釋,顯式關(guān)閉連接:

const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');

async function runApp() {
  let connection;
  try {
    connection = await oracledb.getConnection(dbConfig);
    const result = await connection.execute(`select * from dual`);
    console.dir(result.rows, { depth: null });
    console.log('正在關(guān)閉連接');
    await connection.close(); // 顯式關(guān)閉連接
    console.log('連接已關(guān)閉');
  } catch (err) {
    console.error(err);
  } finally {
    // 在實際應(yīng)用中,通常會在 finally 塊中確保連接關(guān)閉
    // if (connection) {
    //   try {
    //     await connection.close();
    //   } catch (err) {
    //     console.error(err);
    //   }
    // }
  }
}

runApp();
登錄后復(fù)制

再次運行,延遲便會消失:

$ time node t.js
[ [ 'X' ] ]
正在關(guān)閉連接
連接已關(guān)閉

real    0m0.249s # 實際執(zhí)行時間恢復(fù)正常
user    0m0.082s
sys 0m0.017s
登錄后復(fù)制

在 node-oracledb 的早期版本或使用 Thick 模式時,即使不顯式關(guān)閉連接,也通常不會出現(xiàn)這種延遲。

深入解析:Thin 模式下的資源管理

這種行為上的差異源于 node-oracledb 6.0 Thin 模式與 Thick 模式(或早期版本)在底層網(wǎng)絡(luò)資源管理方式上的根本不同。

AI建筑知識問答
AI建筑知識問答

用人工智能ChatGPT幫你解答所有建筑問題

AI建筑知識問答22
查看詳情 AI建筑知識問答
  1. Thin 模式的工作原理: 在 node-oracledb 6.0 的 Thin 模式中,該模塊直接管理與 Oracle 數(shù)據(jù)庫建立的網(wǎng)絡(luò)套接字(sockets)。這些套接字是 Node.js 事件循環(huán)已知的資源。這意味著,只要這些套接字處于打開狀態(tài),Node.js 的事件循環(huán)就會認為仍有待處理的 I/O 操作,從而阻止應(yīng)用程序立即終止。 當(dāng)沒有顯式調(diào)用 connection.close() 時,這些套接字會保持打開狀態(tài)。Node.js 內(nèi)部有一個“終結(jié)注冊表”(finalization registry)機制,它會在持有這些套接字的對象被 JavaScript 垃圾回收器回收時,強制關(guān)閉這些套接字。然而,垃圾回收的時機是不可預(yù)測的,這正是導(dǎo)致腳本在執(zhí)行完畢后出現(xiàn)數(shù)秒不確定延遲的原因。應(yīng)用程序必須等待垃圾回收器介入并清理這些資源后,Node.js 進程才能最終退出。

  2. Thick 模式(或早期版本)的工作原理: 與 Thin 模式不同,在 Thick 模式下或 node-oracledb 的早期版本中,底層的網(wǎng)絡(luò)連接和套接字是由外部的 Oracle 客戶端庫(Oracle Client library)管理的。這個客戶端庫通常是一個 C/C++ 庫,它在 Node.js 進程之外維護這些資源。 對于 Node.js 運行時而言,它對這些由外部庫管理的套接字一無所知,也不會將它們視為需要保持事件循環(huán)活躍的因素。因此,當(dāng) Node.js 腳本中的所有 JavaScript 異步操作完成后,即使 Oracle 客戶端庫內(nèi)部的連接尚未完全關(guān)閉,Node.js 也會認為其事件循環(huán)已空閑,從而愉快地終止進程,不會出現(xiàn)額外的延遲。

解決方案與最佳實踐:顯式關(guān)閉連接

理解了背后的機制,解決方案就變得非常明確:始終顯式關(guān)閉數(shù)據(jù)庫連接。

通過調(diào)用 await connection.close(),我們指示 node-oracledb 立即釋放與該連接關(guān)聯(lián)的所有底層網(wǎng)絡(luò)資源。這會通知 Node.js 事件循環(huán),相關(guān)的 I/O 操作已完成,并且沒有未決的網(wǎng)絡(luò)活動需要等待。一旦所有連接都被顯式關(guān)閉,Node.js 進程便能立即判斷事件循環(huán)已空閑,從而快速終止。

推薦的代碼結(jié)構(gòu):

const oracledb = require('oracledb');
const dbConfig = require('./dbconfig.js');

async function runApp() {
  let connection; // 聲明 connection 變量
  try {
    connection = await oracledb.getConnection(dbConfig);
    const result = await connection.execute(`select * from dual`);
    console.dir(result.rows, { depth: null });
    console.log('數(shù)據(jù)庫操作完成');
  } catch (err) {
    console.error('執(zhí)行數(shù)據(jù)庫操作時發(fā)生錯誤:', err);
  } finally {
    // 確保無論是否發(fā)生錯誤,連接都會被關(guān)閉
    if (connection) {
      try {
        await connection.close();
        console.log('數(shù)據(jù)庫連接已安全關(guān)閉。');
      } catch (err) {
        console.error('關(guān)閉數(shù)據(jù)庫連接時發(fā)生錯誤:', err);
      }
    }
  }
}

runApp();
登錄后復(fù)制

注意事項:

  • try...finally 塊: 在實際應(yīng)用中,使用 try...finally 塊來包裹數(shù)據(jù)庫操作是最佳實踐。這可以確保即使在數(shù)據(jù)庫操作過程中發(fā)生錯誤,連接也能被可靠地關(guān)閉,避免資源泄露。
  • 連接池: 對于長時間運行的應(yīng)用程序(如 Web 服務(wù)器),不應(yīng)在每次請求后立即關(guān)閉連接,而應(yīng)使用 node-oracledb 的連接池功能。連接池會自動管理連接的生命周期,并在應(yīng)用程序退出時負責(zé)關(guān)閉所有池中的連接。然而,對于短生命周期的腳本,顯式關(guān)閉單個連接仍然是必要的。
  • 資源管理的重要性: 顯式關(guān)閉連接不僅僅是為了避免腳本終止延遲,更是良好資源管理的關(guān)鍵。它能防止因未釋放資源導(dǎo)致的內(nèi)存泄漏、端口耗盡或其他潛在的系統(tǒng)不穩(wěn)定問題。

總結(jié)

node-oracledb 6.0 Thin 模式下腳本結(jié)束時的延遲是其底層網(wǎng)絡(luò)資源管理機制的預(yù)期行為。由于 Thin 模式直接管理網(wǎng)絡(luò)套接字并將其注冊到 Node.js 事件循環(huán)中,這些未關(guān)閉的套接字會阻止進程立即終止。通過在代碼中顯式調(diào)用 await connection.close(),開發(fā)者可以確保網(wǎng)絡(luò)資源及時釋放,從而實現(xiàn)腳本的即時終止,并遵循數(shù)據(jù)庫連接管理的最佳實踐。這一改變強調(diào)了在現(xiàn)代 Node.js 數(shù)據(jù)庫驅(qū)動中,對資源生命周期進行精確控制的重要性。

以上就是解決 node-oracledb 6.0 Thin 模式腳本結(jié)束延遲問題的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!

最佳 Windows 性能的頂級免費優(yōu)化軟件
最佳 Windows 性能的頂級免費優(yōu)化軟件

每個人都需要一臺速度更快、更穩(wěn)定的 PC。隨著時間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺進程會占用資源并降低性能。幸運的是,許多工具可以讓 Windows 保持平穩(wěn)運行。

下載
來源:php中文網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn
最新問題
開源免費商場系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長!
關(guān)注服務(wù)號 技術(shù)交流群
PHP中文網(wǎng)訂閱號
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號