使用 EF 时数据库连接丢失时如何捕获异常?
How to catch exception when database connection is lost when using EF?
我正在使用数据库中的 ADO.NET 实体数据模型 EF 设计器。我的 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
有什么办法可以解决这个问题吗?
对于弹性和自定义处理,答案是相同的。您需要配置策略:
以下代码启用失败重试:
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: The underlying provider failed on Open. ---> System.Data.SqlClient.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. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception: Access is denied
In first request I got the above error and after the immediate another request I does not get any error and request is successful.
在做了一些 Google 之后,我得到了我在我的应用程序中实现的连接弹性之类的概念,它可以工作并在特定时间段后的特定时间重试查询。
但是在我使用上面代码中的自定义事务的情况下它失败了。它抛出这样的错误。
System.InvalidOperationException: The configured execution strategy 'MYExecutionStrategy' does not support user initiated transactions. See http://go.microsoft.com/fwlink/?LinkId=309381 for additional information.
I configured the Execution Strategy like this:
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;
}
}
我正在使用数据库中的 ADO.NET 实体数据模型 EF 设计器。我的 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
有什么办法可以解决这个问题吗?
对于弹性和自定义处理,答案是相同的。您需要配置策略:
以下代码启用失败重试:
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: The underlying provider failed on Open. ---> System.Data.SqlClient.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. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) ---> System.ComponentModel.Win32Exception: Access is denied In first request I got the above error and after the immediate another request I does not get any error and request is successful.
在做了一些 Google 之后,我得到了我在我的应用程序中实现的连接弹性之类的概念,它可以工作并在特定时间段后的特定时间重试查询。
但是在我使用上面代码中的自定义事务的情况下它失败了。它抛出这样的错误。
System.InvalidOperationException: The configured execution strategy 'MYExecutionStrategy' does not support user initiated transactions. See http://go.microsoft.com/fwlink/?LinkId=309381 for additional information. I configured the Execution Strategy like this:
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;
}
}