vb.net每秒轮询Sql server一次,导致超时
我被要求执行一个系统,该系统将每秒轮询数据库中的一个表,如果它对符合条件的行进行计数,则启动操作以处理该行 我曾经这样做过,但偶尔我会遇到一个超时异常。我有一个WPF应用程序,其中有一个在后台运行的线程。此线程有一个循环,并在循环结束时休眠一秒钟。到数据库的连接在“using”子句中打开 下面是我的线程子:vb.net每秒轮询Sql server一次,导致超时,sql,vb.net,sql-server-2008,tsql,vb.net-2010,Sql,Vb.net,Sql Server 2008,Tsql,Vb.net 2010,我被要求执行一个系统,该系统将每秒轮询数据库中的一个表,如果它对符合条件的行进行计数,则启动操作以处理该行 我曾经这样做过,但偶尔我会遇到一个超时异常。我有一个WPF应用程序,其中有一个在后台运行的线程。此线程有一个循环,并在循环结束时休眠一秒钟。到数据库的连接在“using”子句中打开 下面是我的线程子: Private Sub PollDatabase() While m_StopThread = False Try Dim listOfRows As L
Private Sub PollDatabase()
While m_StopThread = False
Try
Dim listOfRows As List(Of DataObject) = db.GetDataObjects()
... Do something with the rows ...
Catch ex As Exception
m_log.WriteLine(ex.ToString())
End Try
Thread.Sleep(1000)
End While
End Sub
我的SQL函数如下所示:
Public Function GetDataObjects() As List(Of DataObject)
Dim result As New List(Of DataObject)
Dim sb As New StringBuilder("... the sql query ...")
Using cnn = New SqlConnection(_connectionString)
cnn.Open()
Using cmd = New SqlCommand(sb.ToString(), cnn)
cmd.CommandTimeout = 0
Using DataReader As SqlDataReader = cmd.ExecuteReader()
Do While DataReader.Read()
... read the columns from table
to the dataobject ...
result.Add(DataObject)
Loop
End Using
End Using
End Using
Return result
End Function
现在,我的日志出现超时异常:
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
...
at System.Data.SqlClient.SqlConnection.Open()
我的问题是:这真的是一种可行的方法吗?还是我在做一些根本错误的事情?当然,如果有人建议解决这个问题
编辑:
我尝试了一种与SQL函数稍有不同的方法。现在,当我的应用程序启动并转储“using”子句时,我打开了一次连接。我的函数现在看起来像这样:
Public Function GetDataObjects() As List(Of DataObject)
Dim result As New List(Of DataObject)
Dim sb As New StringBuilder("... the sql query ...")
_sqlCmd.CommandText = sb.ToString()
Using DataReader As SqlDataReader = _sqlCmd.ExecuteReader()
Do While DataReader.Read()
... fill the list with objects ...
Loop
End Using
Return result
End Function
我的日志是干净的形式错误。所以,是否有什么错误,打开连接到服务器一秒钟一次,因为我做的使用
编辑:
我现在已经做了很多测试来确定问题。我发现,只需多次连接到服务器不会导致任何问题。在连接之后添加select语句也不起作用。但是当我实际实现一个函数,其中是完整的阅读器部分并返回结果时,我遇到了超时问题。这里有两个例子
这不会引起问题:
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
Me.DataContext = Me
m_Thread = New Thread(AddressOf ConnectionTestFunction)
m_Thread.IsBackground = True
m_Thread.Start()
End Sub
Private Sub ConnectionTestFunction()
While m_stopThread = False
Try
m_log.WriteLine("GetData (" & m_ThreadCounter & ")")
Using cnn As SqlConnection = New SqlConnection("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True")
cnn.Open()
Using cmd As SqlCommand = New SqlCommand("SELECT * FROM Data", cnn)
Using DataReader As SqlDataReader = cmd.ExecuteReader()
Do While DataReader.Read()
Loop
End Using
End Using
End Using
Catch ex As Exception
m_log.WriteLine(ex.ToString())
End Try
m_ThreadCounter += 1
Thread.Sleep(1000)
End While
End Sub
这会导致超时错误:
Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
Me.DataContext = Me
m_Thread = New Thread(AddressOf ConnectionTestFunction)
m_Thread.IsBackground = True
m_Thread.Start()
End Sub
Private Sub ConnectionTestFunction()
While m_stopThread = False
Try
m_log.WriteLine("GetData (" & m_ThreadCounter & ")")
Dim datarows As List(Of Data) = Me.GetData()
Catch ex As Exception
m_log.WriteLine(ex.ToString())
End Try
m_ThreadCounter += 1
Thread.Sleep(1000)
End While
End Sub
Private Function GetData() As List(Of Data)
Dim result As New List(Of Data)
Using cnn As SqlConnection = New SqlConnection("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True")
cnn.Open()
Using cmd As SqlCommand = New SqlCommand("SELECT * FROM Data", cnn)
Using DataReader As SqlDataReader = cmd.ExecuteReader()
Do While DataReader.Read()
Dim d As New Data()
d.DataId = DataReader("DataId")
... etc fields about 10 of them ...
result.Add(d)
Loop
End Using
End Using
End Using
Return result
End Function
如果有人对此有任何想法,我真的很高兴。。。我必须承认,我现在真的很困惑。可能您的代码比连接的默认超时值需要更长的时间才能完成。尝试在创建Sql连接时指定超时。确保它比代码需要完成的时间长。这种方法似乎不是很好。。为什么不在新数据出现时做出反应,而不是共享?您可以使用触发器或SqlDependency
您查看过SQL日志吗?您的服务器正忙吗?你在同一个盒子上安装了Exchange吗?嘿,Peter,不,我没有Exchange。服务器的使用不是很频繁。大约有五个ppl在内部使用。嗯。。服务器上发生了一些问题。根据日志,有一个中国IP地址每秒试图连接sa帐户不止一次。我猜这可能会造成一些滞后?我不是SQL server或网络专业人士。这可能不相关——假设他们只是想加入,而不是成功。IME如果您在internet上公开了SQL Server(最好避免使用poss,但不总是poss),那么它将不可避免地成为此类攻击的目标。至少,删除sa帐户,如果可以的话,限制对已知ip地址范围的访问;尽可能把它藏起来。他们不是针对你——他们只是四处走动,试着把门把手。在您打开一个连接并保持它打开的情况下,没有什么不对的。编辑我的问题以显示我用来测试服务器的两段代码,以找出到底出了什么问题。呵呵,我无法在SQL server上执行任何操作。我无法添加触发器、过程等。。但是我可以用我的vb.net代码做任何事情。我将看一看SQLDependence,这对我来说是一个新的主题。不幸的是,SQLDependence看起来也不成问题:(.这可能是一个非常好的解决方案,看起来应该使用一些东西,但我的老板说,由于我们在其他地方有类似的代码,我们应该以同样的方式来做,并找出为什么我在“使用”时会出错子句,而不是只打开一个连接,而不是试图绕过这个问题。所以我的问题仍然是,每次需要提交一些sql时打开一个新连接是错误的吗?