我正在使用azure表查询来检索分配给用户的所有错误实体。 此外,我更改实体的属性以声明实体处于处理模式。 处理完实体后,我从表中删除了实体。
当我进行并行测试时,可能会发生在查询期间,实体已被另一个线程处理和删除。因此,当我想替换实体时,我得到错误404 ResourceNotFound。
有没有办法测试,如果实体在线程之外被更改或者它是否仍然存在?是否更好地捕获错误404并忽略它或者我应该再次查询实体(似乎一切都不适合我)?
TableQuery<ErrorObjectTableEntity> query = new TableQuery<ErrorObjectTableEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, user));
List<ErrorObjectTableEntity> queryResult = table.ExecuteQuery(query).OrderBy(x => x.action).ToList();
foreach (ErrorObjectTableEntity entity in queryResult)
{
entity.inProcess = true;
try
{
TableOperation updateOperation = TableOperation.Replace(entity);
table.Execute(updateOperation);
}
catch
{
//..some logging here
//catch error 404?
}
//do some action
try
{
TableOperation deleteOperation = TableOperation.Delete(entity);
table.Execute(deleteOperation);
}
catch{...}
}
答案 0 :(得分:0)
你应该抓住404错误。尽管它们在.NET中表示为异常,但HTTP 4xx错误代码比异常更具信息性。 (5xx错误代码例外。)
即使您在执行替换之前检查了实体是否存在,您仍然需要捕获NotFound错误,以防它在检查和替换调用之间被删除。所以你不妨跳过检查。
答案 1 :(得分:0)
就最佳做法而言,这里有几个问题。您编写的代码可以简单地忽略该异常,假设另一个工作程序删除了它,但这最终可能会掩盖其他类错误。一种解决方案是使用队列按用户查询插入消息,然后让各种工作人员检索消息并处理特定用户的查询。这样,如果节点发生故障,应用程序将吸收故障并继续。此外,这将使您的工作人员不会重复工作,从而优化整个应用程序。最后,如果您不关心实体的状态并且键是可预测的,您可以使用Merge语义来简单地更新实体的给定属性而不替换整个事物。