首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实体框架6和连接Resiliency的自定义执行策略

实体框架6和连接Resiliency的自定义执行策略
EN

Stack Overflow用户
提问于 2017-08-08 09:03:46
回答 1查看 5.6K关注 0票数 2

我已经用EF6和MS开发了一个应用程序。

在我的应用程序中的任何地方,我都编写了如下代码,需要在其中插入、更新或删除表中的数据:

代码:

代码语言:javascript
复制
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:在建立到Server的连接时发生了与网络相关的或特定于实例的错误.找不到或无法访问服务器。验证实例名是否正确,以及Server是否配置为允许远程连接。(提供程序:命名管道提供程序,错误: 40 -无法打开到Server的连接)--> System.ComponentModel.Win32Exception:访问被拒绝

在第一次请求中,我得到了上面的错误,在立即的另一个请求之后,我没有得到任何错误,请求是成功的。

在做了一些Google之后,我得到了像连接Resiliency这样的概念,我在我的应用程序中实现了这个概念,它在特定的一段时间后工作并重新尝试了一些特定的查询。

但是,在我使用自定义事务的地方,它会失败,就像在上面的代码中一样。它像这样抛出错误。

System.InvalidOperationException:配置的执行策略“MYExecutionStrategy”不支持用户发起的事务。有关其他信息,请参见http://go.microsoft.com/fwlink/?LinkId=309381

我将执行策略配置如下:

代码语言:javascript
复制
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是这样的:

代码语言:javascript
复制
/// <summary>
/// 
/// </summary>
public class MYConfiguration : DbConfiguration
{
    /// <summary>
    /// 
    /// </summary>
    public MYConfiguration()
    {
        SetExecutionStrategy("System.Data.SqlClient", () => new MYExecutionStrategy(3, TimeSpan.FromSeconds(1)));            
    }
}

问题:

  1. 如何使用实体框架6中的连接Resiliency和自定义事务。
  2. 我找不到DatabaseFacade类或命名空间。
EN

回答 1

Stack Overflow用户

发布于 2017-08-08 12:24:30

对于自定义事务,如果在第二个SaveChanges()上出现连接故障,那么第一个SaveChanges()也将被回滚。你打算怎么再试一次?这就是为什么EF重试只支持每个事务一个SaveChanges()。

向前迈进的一种方法是从Demo1()和Demo2()中删除Demo1(),并在调用方法中有一个SaveChanges(),而不是一个事务。

另一种方法是在调用方法中捕获异常并在那里编排重试。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45563977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档