连接设置被覆盖

问题描述 投票:0回答:1

服务(Windows服务)用于创建多个线程并执行每个线程负责的不同区域。对于两个特定线程,连接字符串和设置似乎被覆盖。这两个线程在某个时刻调用同一个类来执行需求。这两个线程都使用不同的数据库连接字符串,因此数据库托管在两个不同的区域。问题是,需要处理的记录是从正确的数据库中获取的,并且错误(由于不正确的设置)被返回并记录在不正确的数据库上。此问题是间歇性的,不会定期发生。正在处理的记录将因此问题而失败,但是当 1 分钟后运行同一记录时,一切都会成功(正确的数据库连接和设置)

类中发起的两个线程: 连接字符串位于通过 DBUtils 类检索的数据库中

    Public Class MyClassName
       Private WithEvents MyTimer As Timers.Timer = Nothing 
       Private eveHUBSPOTUPDATEEVENTS_NZ As New Threading.Thread(AddressOf EventHubSpotUpdateEvents)
       Private eveSYSEVENTS_AUS As New Threading.Thread(AddressOf EventSystemEvents_Aus)
    End Class

类的构造函数

   Public Sub New()
   InitializeComponent()
   //other config settings

   ServicePointManager.SecurityProtocol = Net.SecurityProtocolType.Tls12 Or Net.SecurityProtocolType.Tls11 Or Net.SecurityProtocolType.Tls Or Net.SecurityProtocolType.Ssl3
   End Sub

启动事件

    Protected Overrides Sub OnStart(ByVal args() As String)
     SetTimerProps(False)
    End Sub

    Private Sub SetTimerProps(ByVal doDisable As Boolean)
ClearCounters()

If doDisable Then
    If MyTimer IsNot Nothing Then
        MyTimer.Enabled = False
        MyTimer = Nothing
    End If
Else
    _mustDoHubspotEventsNZ = MustDOHubSpotEventsNZ()
    _mustDoHubspotEvents_Aus = MustDoHubSpotEvents_Aus()

    MyTimer = New Timers.Timer With {
        .Interval = 10000,                '10 Seconds
        .AutoReset = False,
        .Enabled = True
    }
End If

结束子

然后在计时器上创建线程(与上面相同的类):

    Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs) Handles MyTimer.Elapsed
       Try
         MyTimer.Enabled = False
         IncrementCounters()

         If Not eveHUBSPOTUPDATEEVENTS_NZ.IsAlive Then
           eveHUBSPOTUPDATEEVENTS = New Threading.Thread(AddressOf EventHubSpotUpdateEvents) With {
          .IsBackground = True,
          .Priority = Threading.ThreadPriority.Normal
         }
           eveHUBSPOTUPDATEEVENTS_NZ.Start()
       End If

      If nSYSEVENTS_AUS_Counter > 1 AndAlso Not eveSYSEVENTS_AUS.IsAlive Then
        nSYSEVENTS_AUS_Counter = 0

        If _mustDoSystemEvents_Aus Then
           eveSYSEVENTS_AUS = New Threading.Thread(AddressOf EventSystemEvents_Aus) With {
           .IsBackground = True,
           .Priority = Threading.ThreadPriority.Highest
         }
         eveSYSEVENTS_AUS.Start()
        End If
     End If
      Catch ex As Exception
       //Error Handling
       MyTimer.Enabled = True
    End Sub

这两个线程都会转到一个方法来检索需要处理的记录。

对于 NZ 进程,连接字符串

    Public Class EventsNZ
       Public Sub New()
         _connectionString = DBUtils.SureSetting.GetSetting("ConnStringNZ")
         _environment = DBUtils.SureSetting.GetSetting("Environment")
       End Sub
    End Class

对于 Aus 进程,连接字符串

    Public Class EventsAus
       Public Sub New()
         _connectionString = DBUtils.SureSetting.GetSetting("ConnStringAus")
         _environment = DBUtils.SureSetting.GetSetting("Environment")
       End Sub
    End Class

然后检索记录(新西兰):

    Private Sub HandleEventsNZ()
      Try
        Const sqlEvents = "script to retrieve the required records"

        Dim systemEventsData = _dbHelper.GetLongRunningSQLDataTable(sqlEvents, 600, Nothing)
    
        For Each eventItem As DataRow In systemEventsData.Rows()
         Dim feedback = HandleHubspotEvent(eventItem, _connectionString )

         UpdateEventToCompleted(StringAsLong(eventItem("Sys_Key")), feedback)
       Next

       systemEventsData.Dispose()
    Catch ex As Exception
      //some error handling
    End Try
  End Sub

    Private Function HandleHubspotEvent(eventData As DataRow, dbConnectionString As String) As String
      Try
       //some validations

       Dim hubspotWorker As New HubspotIntegrator(_connectionString, productId, StringAsInteger(eventData("User_Cde")))

       Return hubspotWorker.HubspotCreateOrUpdate(eventData("Area_Cde").ToString(),
                                        StringAsLong(eventData("Reference_Cde")),
                                        eventData("Other_Ref2").ToString(), eventResult)

   Catch ex As Exception
    //error handling
   End Try
 End Sub
End Function

然后检索记录(澳大利亚): 检索记录的过程类似。由于即将发生的移民,澳大利亚只能属于自己的类别。一旦Aus数据迁移到NZ端,这个类和对应的线程就会被移除。

Aus会达到这个方法:

    Private Function HandleHubspotEvent(ByRef eventData As DataRow) As String
       Try
         //some validation

         Dim hubspotWorker As New HubspotIntegrator(_connectionString, productId, StringAsInteger(eventData("Event_User_Cde")))

         Return hubspotWorker.HubspotCreateOrUpdate(eventData("Event_Area_Cde").ToString(),
                                        StringAsLong(eventData("Event_Reference_Cde")),
                                        eventData("Event_Other_Ref2").ToString(), "")

    Catch ex As Exception
       //error handling
    End Try
  End Function

到目前为止,已使用正确的连接。 他们都到达同一个班级来处理这个过程。

调用 HubspotIntegrator 类时,连接是使用不可变属性设置的。连接在过程中的任何地方(或任何设置)都不会更改。连接字符串传递给此类。但由于某种原因,连接字符串最终在该过程中被更改。

    Public Sub New(ByVal dbConnectionString As String, ByVal productId As Integer, ByVal userId As Integer)
If String.IsNullOrEmpty(dbConnectionString) OrElse dbConnectionString = "" Then
    Throw New ArgumentException("Invalid Connection String!")
End If
If productId = 0 Then
    Throw New ArgumentException("Invalid Product ID!")
End If

_dbConnectionString = dbConnectionString
_dbHelper = New DBUtil(_dbConnectionString)
_dbLookup = New SureDBLookup(dbConnectionString)
_sureQuote = New SureQuote(dbConnectionString)
_productId = productId
_systemMappingWorker = New SureSystemMapping(_dbConnectionString)
_userId = userId
_hsDataHelpers = New HubspotDataHelpers(dbConnectionString)

Dim productRuleData = _dbLookup.GetProductRuleData(productId, 0, "ALLOW_HUBSPOT", Nothing)
If productRuleData Is Nothing OrElse productRuleData("Pro_Val1").ToString <> "Y" Then
    Throw New ArgumentException("Invalid Product ID! Not a HubSpot product")
End If

_hubspotBearerToken = DBUtils.SureSetting.GetSetting(productRuleData("Pro_Val2").ToString().Trim())

If _hubspotBearerToken = Nothing Then
    Throw New ArgumentException("Invalid Hubspot BearerToken - HUBSPOT_BEARERTOKEN is not defined")
End If

结束子

任何关于为什么/如何发生这种情况的建议将不胜感激?如果有什么我遗漏的东西我可以看看(已经看了一周但仍然没有看到问题)

sql vb.net thread-safety windows-services
1个回答
0
投票

在我看来,检索连接字符串和环境的两个函数都设置相同的顶级变量 _connectionString 和 _environment。 由于它们在单独的线程中运行,因此看起来可能部分工作正常,但正如您所指出的,连接字符串会发生更改,因为两个函数调用之一正在覆盖它。

您的 HandleEventsNZ 子程序如何知道要使用哪个连接字符串?

© www.soinside.com 2019 - 2024. All rights reserved.