簡體   English   中英

輪詢數據庫時最好的方法是什么?

[英]What is the best approach while polling database?

目前我正在做一個作業,其中我需要訪問n個服務器的數據庫以獲取一些結果。我通過遍歷服務器列表並為集合中的每個服務器提出任務來實現這一目標。 該任務調用一個函數,該函數基本上與數據庫建立連接,運行查詢並與數據庫斷開連接。

我的問題是,通過對數據庫的每次輪詢建立一個新的連接並每次都關閉它,我做對了嗎?或者這是保持數據庫連接打開並獲取結果,然后在下一次輪詢迭代中保持打開狀態的最佳方法。 每次計時器都會調用PollingServerTimer()。我的輪詢計時器為3秒。

像這樣的東西:

private void PollingServerTimer(object sender, ElapsedEventArgs e)
{            
    foreach (var item in ServerOperationCollHandler)
    {
        if (item.RebootStatus != true)
        {
            PushItemIntoQueue(item);
        }
    }
}

public void PollingServerQueue()
{
    while (isRunning)
    {
        this.waitHandle.WaitOne();

        lock (syncRoot)
        {
            if (ServerQueue.Count > 0)
            {
                ServerOperationDataModel obj;
                try
                {
                    ServerQueue.TryDequeue(out obj);

                    Task GetCountFromDbTask = new Task(() => GetCountFromDb(obj));
                    GetCountFromDbTask.Start();

                    this.waitHandle.Reset();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Problem encountered while finding iterim and recovery count");
                    isRunning = false;
                    break;
                }
            }
        }
    }
}

public void GetCountFromDb(ServerOperationDataModel obj)
{
    ServerOperationDataModel serverObject = (ServerOperationDataModel)obj;
    DataBaseHandler dbHandler = new DataBaseHandler(serverObject.DataBaseIP, serverObject.DataBasePort, serverObject.DataBaseName, serverObject.DataUserName, serverObject.DataUserPassword);

    int attempts = 0;

    do
    {
        try
        {
            dbHandler.connect();
        }
        catch (Exception ex)
        {
            break;
            serverObject.DataBaseConnectionStatus = false;
            log.Error("Connection attempt " + attempts + " failed.Retrying connection. Exception details :" + ex.ToString());
            attempts++;
        }
    } while (attempts < _connectiontRetryAttempts && !dbHandler.isConnected());

    if (dbHandler.isConnected())
    {
        /*Fetch Result and then get disconnect*/
        dbHandler.disConnect();
    }
    else
    {
        //string msgLog = "Server : " + obj.ServerComponentIdentifier + " | " + obj.IPstring + "Connection cannot be established with the DB: " + obj.DataBaseIP + " | "+ obj.DataBasePort + " | " + obj.DataBaseName + " after a series of retries";
        //LoggerUpdate.LogMessage(msgLog, LOGTYPE.POLLINGDATABASE, LoggerUpdate.ReturnLogDisplayObject(DateTime.Now, obj.ServerComponentIdentifier + "|" + obj.IPstring, Convert.ToInt16(LOGTYPE.POLLINGDATABASE), obj, msgLog));
    }
}

我一點也不擔心。 假設您連接到SQL Server(或類似的企業級DBMS),則數據庫連接將在客戶端池中進行,這意味着僅當客戶端首次連接到特定數據庫(正式而言:連接到新數據庫,以前看不見的連接字符串),然后到同一數據庫的每個連接幾乎不花任何費用。

如果沒有用於池化,則應用程序服務器將無法處理數百個查詢同一數據源的並發瀏覽器連接。 每3秒您將需要的不僅僅是連接,否則會導致耗盡服務器或客戶端資源的任何風險。

您可以閱讀有關池工作原理的更多信息

https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/sql-server-connection-pooling

附帶說明:您應該稍微完善一下代碼。

例如,你有

GetCountFromDb(ServerOperationDataModel obj)

但是之后

ServerOperationDataModel serverObject = (ServerOperationDataModel)obj;

為什么需要將obj轉換為相同類型的另一個變量?

catch子句中,您有break和它下面的一些代碼似乎無法到達。

看一下.NET SqlDependency對象。 這使您可以向數據庫注冊查詢,並使用OnChange處理程序在查詢結果更改時接收通知。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM