2017-07-07 61 views
0

我會嘗試儘可能清楚我的問題。如果存在斷開連接,MSSQL會提取連接

我使用這個特定的版本:https://github.com/patriksimek/node-mssql/tree/v3.3.0#multiple-connections mssql npm包。

我一直在尋找通過繁瑣的(潛在的LIB)和微軟文檔的單證(見上面的鏈接GitHub的)

我無法找到任何東西,做一些簡單的像getCurrentConnection,或getConnectionStatus或任何類似。

我有兩種方法來解決這個問題,但我不滿意他們兩個,所以這就是爲什麼我在這裏問。

我的第一種方法是設置一個超時並讓connect函數在每個catch(err)上調用它自己。

第二個是在中間件中處理這個問題,但如果所有工作都正常,它將在每個請求上連接到SQL並再次關閉該連接。

我的中間件功能:

api.use(function(err, req, res, next){ 
    sql.close(); 
    sql.connect(config.database).then(() => { 
    next(); 
    }).catch(function(err) { 
    sql.close(); 
    server.main(); 
    }); 
}); 

PS所以要清楚,我想,如果可能的話拿起連接,而不是結束,並開始與問候一個新來當服務器或數據庫崩潰,我仍然有一些來自興奮功能的數據。

希望我清楚了。

回答

1

在Arnold的幫助下,我瞭解了mssql包,它的內部工作原理好得多。

爲此,我想出了以下解決方案來解決我的問題。

let intervalFunction; 
const INTERVAL_DURATION = 4000; 

if (require.main === module){ 
    console.log("Listening on http://localhost:" + config.port + " ..."); 
    app.listen(config.port); 
    // try to connect to db and fire main on succes. 
    intervalFunction = setInterval(()=> getConnection(), INTERVAL_DURATION); 
} 

function getConnection() { 
    sql.close(); 
    sql.connect(config.database).then(() => { 
    sql.close(); 
    clearInterval(intervalFunction); 
    main(); 
}).catch(function(err) { 
    console.error(err); 
    console.log(`DB connection will be tried again in ${INTERVAL_DURATION}ms`) 
    sql.close(); 
    }); 
} 

一旦初始連接已建立,但它迷路了在此期間,池將自動拿起連接和處理您的連接

0

如果我正確理解你,你基本上想重用連接。繁瑣內置了連接池,所以你不必擔心重新使用它們:

var config = { 
    user: '...', 
    password: '...', 
    server: 'localhost', 
    database: '...', 
    pool: { 
     max: 10, 
     min: 0, 
     idleTimeoutMillis: 30000 
    } 
} 

在上述第(剛剛從您發佈GitHub的URL複製)的例子中,將有10池中的連接可以使用。這就是美麗:池管理器將處理所有連接的使用和重用,也就是說,根據應用程序的需要,連接的數量是彈性的。

正如你所說,DB崩潰怎麼樣?這也是內置的:連接健康檢查:

在內部,每個連接實例是TDS 連接的單獨池。創建新的請求/事務/準備聲明後,將從池中獲取新的TDS連接,並保留 以執行所需的操作。一旦動作完成,連接被釋放回池中的 。連接健康檢查是內置的,所以一旦發現死亡連接 ,它立即被替換爲 新的連接。

我希望這有助於!

+0

嗨阿諾德,感謝您的快速回復,這個事情你描述所有去了解你的關係。但在我的問題中,我指定有時我們的api在db之前啓動。你會怎麼做?我指定的方式,但不是在中間件功能?因此,不斷重試catch(err)還是沒有超時更清晰的方式? – Knopfler

+0

如果我使用這段代碼: '代碼' function getConnection(){ sql.close(); ()();> sql.connect(config.database).then(()=> { sql.close(); main(); console.log('werkt wel'); })。catch(function(err) ()=> { getConnection(),2000 }) });}};}}; } 'code' 而且我用docker打開sql server啓動超時功能就會停止。一旦我重新啓動節點進程,它就會工作,但我不想這樣做。 – Knopfler

+0

對不起,對於遲到的回覆,但國際海事組織你有兩個選擇來解決這個賽車條件(數據庫沒有準備好,當應用程序啓動):1)未能啓動應用程序。這就是我通常所做的。然後我在啓動腳本中處理這個問題。在我的情況下,如果數據庫沒有準備好,根本就沒有必要啓動應用程序(!)。 2)讓應用繼續輪詢數據庫並繼續直到數據庫準備就緒。這也沒關係,但是如果數據庫永遠不會準備好,那麼在某個時候這需要失敗。它看起來就是你在下面做的。 – arnold