可以方便地覆盖System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)方法,以便在插入,更新或删除记录时发生暂时性错误(例如死锁或超时)时重试。
我的问题是,是否有一个类似的函数可以在执行LINQ to SQL查询时重写以处理此类错误?我猜/希望在DataContext类中有一个方法可以对数据库进行实际调用,并且可以重写该方法以执行重试。
我见过的例子(如下所示)通常包装LINQ表达式和在重试块中枚举它的方法调用:
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");
}
}
我希望每次枚举LINQ表达式时都避免这样做。此外,由于延迟加载,对数据库的实际调用可能在时间和代码上与LINQ表达式很好地分开,因此如果可以在较低级别处理重试,则会更安全。
答案 0 :(得分:0)
您可以通过创建一个为您执行重试的扩展方法来完成它:
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();