gpt4 book ai didi

c# - 在出现暂时性错误时重试 LINQ to SQL 查询

转载 作者:行者123 更新时间:2023-11-30 13:04:50 25 4
gpt4 key购买 nike

覆盖 System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode) 方法很方便,以便在插入、更新或删除记录时出现暂时性错误(例如死锁或超时)时重试。

我的问题是,在执行 LINQ to SQL 查询时,是否有可以重写的类似函数来处理此类错误?我猜测/希望 DataContext 类中会有一个方法来执行对数据库的实际调用,并且可以重写该方法以执行重试。

我见过的示例(如下所示)通常将 LINQ 表达式和枚举它的方法调用包装在重试 block 中:

try
{
e.Result = retry.ExecuteAction(() =>
{
Deadlock(); // Artificially create a deadlock condition

CustomerOrdersDataContext ctx = new CustomerOrdersDataContext();
ctx.Connection.ConnectionString = builder.ConnectionString;
ctx.CommandTimeout = 3;

var results = from c in ctx.customers
from o in c.orders
from i in o.order_items
select new { c.lname, c.fname, i.product.product_name, i.quantity };

return results.ToList();
});
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message, "SqlException");
}

(来自 http://social.technet.microsoft.com/wiki/contents/articles/retry-logic-for-transient-failures-in-sql-azure.aspx)

我希望避免每次枚举 LINQ 表达式时都必须这样做。此外,通过延迟加载,对数据库的实际调用可以在时间和代码上与 LINQ 表达式很好地分离,因此如果重试可以在较低级别处理会更安全。

最佳答案

您可以通过创建一个为您执行重试的扩展方法来完成它:

public static List<T> ToList_DeadlockRetry<T>(this IEnumerable<T> source, int retryAttempts = 5)
{
while (retryAttempts > 0)
{
try
{
return source.ToList();
}
catch (SqlException ex)
{
retryAttempts--;

if (retryAttempts == 0)
{
throw ex;
}
}
}
}

然后你可以像这样使用它:

var results = from c in ctx.customers
from o in c.orders
from i in o.order_items
select new { c.lname, c.fname, i.product.product_name, i.quantity };

return results.ToList_DeadlockRetry();

关于c# - 在出现暂时性错误时重试 LINQ to SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7155621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com