[英]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. 目前我正在做一个作业,其中我需要访问n个服务器的数据库以获取一些结果。我通过遍历服务器列表并为集合中的每个服务器提出任务来实现这一目标。 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.
每次计时器都会调用PollingServerTimer()。我的轮询计时器为3秒。
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));
}
}
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.
假设您连接到SQL Server(或类似的企业级DBMS),则数据库连接将在客户端池中进行,这意味着仅当客户端首次连接到特定数据库(正式而言:连接到新数据库,以前看不见的连接字符串),然后到同一数据库的每个连接几乎不花任何费用。
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.
每3秒您将需要的不仅仅是连接,否则会导致耗尽服务器或客户端资源的任何风险。
You can read more on how pooling works 您可以阅读有关池工作原理的更多信息
https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling https://docs.microsoft.com/zh-cn/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? 为什么需要将
obj
转换为相同类型的另一个变量?
In the catch
clause, you have break
and some code below it which looks unreachable. 在
catch
子句中,您有break
和它下面的一些代码似乎无法到达。
Take a look at the .NET SqlDependency object. 看一下.NET SqlDependency对象。 This allows you to register a query with a database and, using an OnChange handler, receive notification whenever the result of the query changes.
这使您可以向数据库注册查询,并使用OnChange处理程序在查询结果更改时接收通知。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.