簡體   English   中英

使用 EF 時數據庫連接丟失時如何捕獲異常?

[英]How to catch exception when database connection is lost when using EF?

我正在使用數據庫中的 ADO.NET 實體數據 Model EF Designer。 我的 SQL 服務器在另一台 PC 上,當我失去與數據庫的連接時,我的應用程序停止了,我只能將其關閉。 我得到:

System.Data.Entity.Core.EntityException
  HResult=0x80131501
  Message=The underlying provider failed on Open.
  Source=EntityFramework

Inner Exception 1:
SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.

Inner Exception 2:
Win32Exception: The network path was not found

有什么辦法可以解決這個問題嗎?

對於彈性和自定義處理,答案是相同的。 你需要配置一個策略:

檢查連接彈性: https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency#custom-execution-strategy

以下代碼啟用失敗重試:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
            options => options.EnableRetryOnFailure());
}

如果其中一種內置策略對您來說不夠用,您可以定義自己的策略並在那里處理異常:

這是自定義策略的示例:

using (DemoEntities objContext = GetDemoEntities())
{
    using (TransactionScope objTransaction = new TransactionScope())
    {

        Demo1(objContext);

        Demo2(objContext);

        // Commit the changes in the database.
        objTransaction.Complete();
    }
}

public void Demo1(DemoEntities objContext)
{
    Demo1 objDemo1 = new Demo1();
    objDemo1.Title = "ABC";

    objContext.Demo1.Add(objDemo1);

    objContext.SaveChanges();   
}

public void Demo2(DemoEntities objContext)
{
    Demo2 objDemo2 = new Demo2();
    objDemo2.Title = "ABC";

    objContext.Demo2.Add(objDemo2);

    objContext.SaveChanges();   
}

我的應用程序在一台服務器上運行,數據庫在 AWS 的另一台服務器上運行。

我的應用程序運行順利,但是有 2-3 次我收到如下錯誤。

System.Data.Entity.Core.EntityException:基礎提供程序在打開時失敗。 ---> System.Data.SqlClient.SqlException:建立與 SQL 服務器的連接時發生與網絡相關或特定於實例的錯誤。 服務器未找到或無法訪問。 驗證實例名稱是否正確以及 SQL 服務器是否配置為允許遠程連接。 (提供程序:命名管道提供程序,錯誤:40 - 無法打開與 SQL 服務器的連接)---> System.ComponentModel.Win32Exception:訪問被拒絕得到任何錯誤並且請求成功。

在做了一些谷歌之后,我得到了像我在我的應用程序中實現的連接彈性這樣的概念,它可以工作並在特定時間段后的特定時間重試查詢。

但是在我使用上面代碼中的自定義事務的情況下,它失敗了。 它拋出這樣的錯誤。

System.InvalidOperationException:配置的執行策略“MYExecutionStrategy”不支持用戶啟動的事務。 有關其他信息,請參閱http://go.microsoft.com/fwlink/?LinkId=309381 我這樣配置執行策略:

public class MYExecutionStrategy : DbExecutionStrategy
{
    /// <summary>
    /// The default retry limit is 5, which means that the total amount of time spent 
    /// between retries is 26 seconds plus the random factor.
    /// </summary>
    public MYExecutionStrategy()
    {
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="maxRetryCount"></param>
    /// <param name="maxDelay"></param>
    public MYExecutionStrategy(int maxRetryCount, TimeSpan maxDelay)
        : base(maxRetryCount, maxDelay)
    {
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="exception"></param>
    /// <returns></returns>
    protected override bool ShouldRetryOn(Exception exception)
    {
        bool bRetry = false;

        SqlException objSqlException = exception as SqlException;

        if (objSqlException != null)
        {
            List<int> lstErrorNumbersToRetry = new List<int>()
            {
                5 // SQL Server is down or not reachable
            };

            if (objSqlException.Errors.Cast<SqlError>().Any(A => lstErrorNumbersToRetry.Contains(A.Number)))
            {
                bRetry = true;
            }
        }

        return bRetry;
    }
}

暫無
暫無

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

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