簡體   English   中英

在一段時間后重試功能的最佳方法,然后重試

[英]Best approach to timeout a function after a certain period of time and retry

只是一點點背景。 我們正在從將散列在數據庫中的用戶密碼存儲到直接針對Active Directory進行身份驗證。 不幸的是,我們有太多內部應用程序,以至於此時無法更新每個應用程序。

因此,我認為我可以只為SQL構建一個.NET CLR程序集,並修改現有的身份驗證存儲過程,以針對我們的域控制器(而不是表)驗證用戶密碼,而不是要求所有開發人員更改其代碼。

這在我們的初始測試中是成功的,除了由於某種原因(關閉,重新啟動,網絡等)無法與域控制器通信時。 發生這種情況時,我們會超時。 我添加了一個try / catch和while循環,以僅跳到下一個域控制器並嘗試對其進行身份驗證,但是在嘗試對下一個服務器進行身份驗證之前,它仍然需要20秒鍾以上的首次嘗試失敗。 因為這是SQL程序集/函數,並且在存儲過程中被調用,所以20秒太長了。

什么是修改我的代碼並使對服務器的身份驗證嘗試失敗並在3秒鍾后嘗試下一個服務器的最佳方法? 以某種方式穿線?

Imports System
Imports System.Data
Imports System.Collections
Imports System.Text
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlTypes
Imports System.Runtime.InteropServices
Imports System.DirectoryServices.AccountManagement

Partial Public Class UserDefinedFunctions

    <SqlFunction(Name:="ValidCredentials")>
    Public Shared Function ValidCredentials(ByVal Domain As SqlString, ByVal Username As SqlString, ByVal Password As SqlString) As SqlBoolean
        'Validates the username and password are correct against the domain.

        Dim ServerNum As Integer = 1
        Dim Success As Boolean = False
        Dim ValidCreds As SqlBoolean = False

        'Loop through all 4 domain controllers to attempt authentication against each of them.
        While Success = False And ServerNum <= 4

            Try

                Dim pc As PrincipalContext
                If Domain = "employees" Then
                    pc = New PrincipalContext(ContextType.Domain, "DC-E-0" & ServerNum.ToString & ".employees.ourdomain.loc", "EMPLOYEES\BindAcct", "PASS")
                Else
                    pc = New PrincipalContext(ContextType.Domain, "DC-S-0" & ServerNum.ToString & ".students.ourdomain.loc", "STUDENTS\BindAcct", "PASS")
                End If

                ValidCreds = pc.ValidateCredentials(Username, Password)
                Success = True
                Return ValidCreds

            Catch ex As Exception

                ValidCreds = False
                Success = False
                ServerNum += 1

            End Try

        End While

        Return ValidCreds

    End Function

End Class

您可以使用以下代碼行在sql server 2008或更高版本上為函數設置超時值。 只需將其放在塊的頂部即可:

SET LOCK_TIMEOUT 3000;  
GO

超時值以milliseconds

根據MS文檔

當等待鎖的時間超過超時值時,將返回錯誤。

這將導致您的功能花費少於3秒或失敗。 然后,您應該捕獲異常並在需要時回滾。

您可以使用單獨的線程執行此操作:

設置操作超時

代碼在C#中,但是轉換起來應該很簡單。

暫無
暫無

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

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