我已经使用EF6和MS-SQL Server开发了一个应用程序。
我的应用程序中的所有地方都编写了如下代码,我需要在表格中插入,更新或删除数据:
代码:
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:A 建立时发生与网络相关或特定于实例的错误 与SQL Server的连接。服务器未找到或未找到 无障碍。验证实例名称是否正确以及SQL 服务器配置为允许远程连接。 (提供者:命名 管道提供程序,错误:40 - 无法打开到SQL Server的连接) ---> System.ComponentModel.Win32Exception:访问被拒绝
在第一个请求中我收到了上述错误,并且在另一个请求之后我没有收到任何错误并且请求成功。
在做了一些Google之后我得到了我在我的应用程序中实现的连接弹性这个概念,它可以在某个特定时期后的某些特定时间重试查询。
但是在我使用自定义事务的位置失败了,就像在上面的代码中一样。它会抛出这样的错误。
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;
}
}
和DBConfiguration一样:
/// <summary>
///
/// </summary>
public class MYConfiguration : DbConfiguration
{
/// <summary>
///
/// </summary>
public MYConfiguration()
{
SetExecutionStrategy("System.Data.SqlClient", () => new MYExecutionStrategy(3, TimeSpan.FromSeconds(1)));
}
}
问题:
答案 0 :(得分:0)
如果在第二个SaveChanges()上出现连接失败,则使用自定义事务,第一个SaveChanges()也将回滚。您如何建议重试?你不能。这就是为什么EF重试仅支持每个事务的单个SaveChanges()。
前进的方法是从Demo1()和Demo2()中删除SaveChanges(),并在调用方法中使用单个SaveChanges()而不是事务。
另一种方法是在调用方法中捕获异常并在那里编排重试。
答案 1 :(得分:0)
所以在做了一些RnD并在WEB上阅读后,我找到了这样的解决方案:
ReadString