我不知何故迷失在 SQL Azure 的 SetExecutionStrategy 和 SetTransactionHandler 的文档中。我在 .Net Framework 4.8 winforms 应用程序中使用 Entity Framework 6.5.1 以及 Microsoft.Data.SqlClient。
我想定义重试来构建连接以及执行的操作。 文档指出: SqlAzureExecutionStrategy :一个 IDbExecutionStrategy,用于重试引发由 SQL Azure 瞬时故障引起的异常的操作。
这是否意味着连接和事务都是由此处理的?
到目前为止我所拥有的:
public class DataContextConfiguration : MicrosoftSqlDbConfiguration
{
public DataContextConfiguration()
{
SetProviderFactory(MicrosoftSqlProviderServices.ProviderInvariantName, Microsoft.Data.SqlClient.SqlClientFactory.Instance);
SetProviderServices(MicrosoftSqlProviderServices.ProviderInvariantName, MicrosoftSqlProviderServices.Instance);
SetExecutionStrategy(MicrosoftSqlProviderServices.ProviderInvariantName, () => new MicrosoftSqlAzureExecutionStrategy());
}
}
[DbConfigurationType(typeof(DataContextConfiguration))]
public partial class ExternalModel : DbContext
{
public ExternalModel(): base("name=ExternalModel"){}
public ExternalModel(string connectionString) : base(connectionString){}
}
我的更新代码(可以使用简化的、更复杂的语句):
try
{
//update Table
using (var db = new ExternalModel(ConnectionString))
{
exampledataset.value= true;
db.SaveChanges();
}
}
catch (Exception ex)
{
MyException = ex.Message;
Result = DatabaseResult.UpdateError;
return null;
}
由于 SetExecutionStrategy,db.SaveChanges 也在内部重试,或者我是否需要这个: this.SetTransactionHandler(MicrosoftSqlProviderServices.ProviderInvariantName,() => new CommitFailureHandler());
或者我应该使用 do-while 重试:
try
{
//update Table
using (var db = new ExternalModel(ConnectionString))
{
exampledataset.value= true;
bool saveFailed;
do
{
saveFailed = false;
try
{
db.SaveChanges();
}
catch (DbUpdateException ex)
{
saveFailed = true;
ex.Entries.Single().Reload();
}
} while (saveFailed);
}
}
catch (Exception ex){...}
感谢您的帮助。
不。 将仅使用 ExecutionStrategy 重试 SaveChanges。
请参阅 连接弹性和重试逻辑 EF6
A TransactionHandler 用于解决稍微不同的问题。 有一个很小的窗口,事务可以在服务器上提交,但它提交的信息永远不会到达客户端。 有一个可选的 TransactionHandler 会做额外的工作来发现重试时的命运。
如果没有自定义 TransactionHandler,EF 将简单地重试事务(假设事务失败)。 通常情况下,如果交易确实成功,那么重试将会失败,并且不会造成任何真正的损害。 但是 CommitFailureHandler 可以防止您在这种情况下需要阻止重试。