AlphaWarrior
AlphaWarrior

Reputation: 57

What is the best approach while polling database?

Currently I am doing an assignment in which I need to visit database of n number of servers to fetch some results.I have achieved this by iterating through the list of servers and raising tasks each one for each server in the collection. The task calls a function which basically makes an connection with the database,run query and disconnect from database.

My question is I am doing right by making a new connection on each polling with the database and closing it everytime or is this would be the best approach to keep a db connection open and fetch the result and then keep it open on next polling iteration. PollingServerTimer() is being called by timer everytime.My polling timer is 3 sec.

Something like this :

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));
    }
}

Upvotes: 0

Views: 2558

Answers (2)

Wiktor Zychla
Wiktor Zychla

Reputation: 48230

I would not be concerned at all. Assuming you connect to the SQL Server (or a similar, enterprise DBMS), database connections are pooled at the client side which means that establishing the connection is costly only the first time the client connects to a particular db (formally: to a new, previously unseen connection string) and then each connection to the same database costs almost nothing.

If it hadn't been for pooling, applications servers would not be able to handle hundreds of concurrent browser connections that query the same data source. You would need much more than a connection every 3 seconds to cause any risk of depleting server or client resources.

You can read more on how pooling works

https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling

A side note: You should polish your code a little bit.

For example, you have

GetCountFromDb(ServerOperationDataModel obj)

but then

ServerOperationDataModel serverObject = (ServerOperationDataModel)obj;

Why would you need to cast the obj to another variable of the very same type?

In the catch clause, you have break and some code below it which looks unreachable.

Upvotes: 2

MStew
MStew

Reputation: 1275

Take a look at the .NET SqlDependency object. This allows you to register a query with a database and, using an OnChange handler, receive notification whenever the result of the query changes.

Upvotes: 1

Related Questions