我和一位同事都负责为Azure表存储找到连接重试逻辑。经过一些搜索,我发现了这个非常酷的企业库套件,它包含Microsoft.Practices.TransientFaultHandling命名空间。
在下面的几个代码示例中,我创建了一个Incremental重试策略,并使用retryPolicy的ExecuteAction回调处理程序包装了一个存储调用:
/// <inheritdoc />
public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value)
{
// Define your retry strategy: retry 5 times, starting 1 second apart, adding 2 seconds to the interval each retry.
var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName));
try
{
retryPolicy.ExecuteAction(() =>
{
var tableClient = storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference(SettingsTableName);
table.CreateIfNotExists();
var entity = new Models.Azure.Setting
{
PartitionKey = GetPartitionKey(userId, bookId),
RowKey = GetRowKey(settingId, itemId),
UserId = userId,
BookId = bookId.ToLowerInvariant(),
SettingId = settingId.ToLowerInvariant(),
ItemId = itemId.ToLowerInvariant(),
Value = value.ToString(Formatting.None)
};
table.Execute(TableOperation.InsertOrReplace(entity));
});
}
catch (StorageException exception)
{
ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception);
throw;
}
}
}感觉棒极了,我去给我的同事看,他得意地说,我们可以做同样的事情,而不必包括企业库,因为CloudTableClient对象已经有了一个重试策略的设置器。他的代码看起来像:
/// <inheritdoc />
public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value)
{
var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName));
var tableClient = storageAccount.CreateCloudTableClient();
// set retry for the connection
tableClient.RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(2), 3);
var table = tableClient.GetTableReference(SettingsTableName);
table.CreateIfNotExists();
var entity = new Models.Azure.Setting
{
PartitionKey = GetPartitionKey(userId, bookId),
RowKey = GetRowKey(settingId, itemId),
UserId = userId,
BookId = bookId.ToLowerInvariant(),
SettingId = settingId.ToLowerInvariant(),
ItemId = itemId.ToLowerInvariant(),
Value = value.ToString(Formatting.None)
};
try
{
table.Execute(TableOperation.InsertOrReplace(entity));
}
catch (StorageException exception)
{
ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception);
throw;
}
}我的问题:
除了它们的实现之外,这两种方法之间有什么重大区别吗?他们似乎都实现了相同的目标,但是否有更好的情况下使用一个而另一个呢?
发布于 2013-09-24 03:47:58
从功能上讲,两者是相同的--它们都会在发生瞬态错误时重试请求。然而,差别很小:
在上面的代码示例中,我可以拦截重试操作,如果愿意,可以在那里执行一些操作。这在存储客户端库中是不可能的。
尽管如此,通常建议采用存储客户端库重试策略来重试存储操作,因为它是包的一个组成部分,因此将不断更新对库的最新更改。
https://stackoverflow.com/questions/18969660
复制相似问题