我有间歇性的问题,从一个蓝色的表中删除的对象。它只影响我的1%的尝试,如果稍后再次进行同样的调用,那么它可以正常工作,但我很想知道它背后的原因!我已经使用了我的手指,我发现缺乏关于如何创建非常可靠的删除,插入和更新代码的文档,这是非常令人惊讶的......这一切似乎都有点失误,“尝试它,大部分时间它会工作“错误从碧霞表删除 - ResourceNotFound
编辑:我删除原来在这个问题中的文本,并用全新的文本取代它,以考虑我已经尝试/已经建议的事情。
待办事项表天青从像SQL Azure的间歇性故障困扰。如果是这样,我会尽管“saveChangesWithRetries”会处理这个问题吗?这是错的吗?
所以......相当简单的代码,被称为大约250倍的Azure的网络角色一分钟。天蓝色表格被用作消息传递系统的一部分。消息由一个用户插入,由另一个用户下载,成功下载时,这些消息被标记为已读。
每个用户具有用于未读消息的分区,和用于读消息的分区。因此,要将消息标记为“读取”,它会从未读分区中删除并移入读取分区。
250时该代码每分钟叫,我将在最后SaveChangesWithRetries收到以下错误2和10之间()。内部的例外是:
ResourceNotFound
The specified resource does not exist. RequestId:652a3e13-3911-4503-8e49-6fec32a3c044 Time:2011-09-28T22:09:39.0795651Z
我不会想象一个分区被访问超过每分钟几次。
这是我的代码:
public static void Message_MarkAsRead(int uid)
{
try
{
storageAccount = CloudStorageAccount.Parse(connectionString);
tableClient = new CloudTableClient(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
tableClient.RetryPolicy = RetryPolicies.Retry(retryAmount, TimeSpan.FromSeconds(retrySeconds));
TableServiceContext tableServiceContext = tableClient.GetDataServiceContext();
tableServiceContext.IgnoreResourceNotFoundException = true;
//the messageUserJoinerTable let's us join messageId to userFromId and userToId
//each message is inserted into the tables twice, once into the userFromId partition and also into the userToId partition
#region get the userToId and userFromId for this message uid
List<int> userIds = new List<int>();
var resultsUserIds = from messagesUserJoinerTable in tableServiceContext.CreateQuery<MessageUserJoinerDataEntity>(messageUserJoinerTableName)
where messagesUserJoinerTable.PartitionKey == uid.ToString()
select messagesUserJoinerTable;
foreach (MessageUserJoinerDataEntity messageUserJoiner in resultsUserIds)
{
userIds.Add(messageUserJoiner.UserId);
}
#endregion
#region then we need to check the partition for each of these users and mark the messages as read
if (userIds.Count > 0)
{
foreach (int userId in userIds)
{
var resultsUnreadMessages = from messagesTable in tableServiceContext.CreateQuery<MessageDataEntity>(messageTableName)
where messagesTable.PartitionKey == CreatePartitionKey(userId, false)
&& messagesTable.RowKey == CreateRowKey(uid)
select messagesTable;
//there should only ever be one as duplicate partition/rowkey is not allowed
MessageDataEntity messageUnread = resultsUnreadMessages.FirstOrDefault();
if (messageUnread != null)
{
bool isUnreadMessageDeleted = false;
//shallow copy the message for re-inserting as read
MessageDataEntity messageRead = new MessageDataEntity(messageUnread);
//delete the message
try
{
tableServiceContext.Detach(messageUnread);
tableServiceContext.AttachTo(messageTableName, messageUnread, "*");
tableServiceContext.DeleteObject(messageUnread);
//this is where the error occurs
tableServiceContext.SaveChangesWithRetries();
isUnreadMessageDeleted = true;
}
catch (Exception ex)
{
MyTrace.Trace("AzureCloudTable_" + Service.versionForTracing + ".Message_MarkAsRead. Error.Stage.1: MessageID:" + uid + ", UserID:" + userId + ". " + ex.Message + ex.StackTrace + ", " + ex.InnerException.Message + ex.InnerException.StackTrace, "Error. MarkAsRead");
//check to see if the message we tried to delete has already been deleted
//if so, we just consume this error and continue by inserting the read message
//else, we throw the exception outwards
var resultsUnreadMessagesLastCheck = from messagesTable in tableServiceContext.CreateQuery<MessageDataEntity>(messageTableName)
where messagesTable.PartitionKey == CreatePartitionKey(userId, false)
&& messagesTable.RowKey == CreateRowKey(uid)
select messagesTable;
//there should only ever be one as duplicate partition/rowkey is not allowed
MessageDataEntity messageUnreadLastCheck = resultsUnreadMessages.FirstOrDefault();
if (messageUnreadLastCheck != null)
{
MyTrace.Trace("AzureCloudTable_" + Service.versionForTracing + ".Message_MarkAsRead. Error.Stage.2: MessageID:" + uid + ", UserID:" + userId + ". Message WAS deleted.", "Error. MarkAsRead");
//the message IS deleted, so although I don't understand why getting error in the first
//place, the result should be the same
throw ex;
}
else
{
//the message is NOT deleted, so we may as well give up now as I don't understand
//what's going on
MyTrace.Trace("AzureCloudTable_" + Service.versionForTracing + ".Message_MarkAsRead. Error.Stage.2: MessageID:" + uid + ", UserID:" + userId + ". Message was NOT deleted.", "Error. MarkAsRead");
}
}
//mark the new message as read
if (isUnreadMessageDeleted)
{
messageRead.PartitionKey = CreatePartitionKey(userId, true);
messageRead.IsRead = true;
//check if read message already exists in storage, if not, insert
var resultsReadMessages = from messagesTable in tableServiceContext.CreateQuery<MessageDataEntity>(messageTableName)
where messagesTable.PartitionKey == CreatePartitionKey(userId, true)
&& messagesTable.RowKey == CreateRowKey(uid)
select messagesTable;
//do the insert
if (resultsReadMessages.FirstOrDefault() == null)
{
tableServiceContext.AddObject(messageTableName, messageRead);
tableServiceContext.SaveChangesWithRetries();
}
}
}
}
}
#endregion
}
catch (Exception ex)
{
try
{
MyTrace.Trace("AzureCloudTable_" + Service.versionForTracing + ".Message_MarkAsRead. Error: " + ex.Message + ex.StackTrace + ", " + ex.InnerException.Message + ex.InnerException.StackTrace, "Error. MarkAsRead");
}
catch (Exception)
{
MyTrace.Trace("AzureCloudTable_" + Service.versionForTracing + ".Message_MarkAsRead. Error: " + ex.Message + ex.StackTrace, "Error. MarkAsRead");
}
}
}
我不明白怎么能资源可能不存在,当它被退回到我作为查询的一部分,然后我做了= NULL检查一下。
根据以往的回应,我添加代码来执行额外的检查,在尝试看看,如果该对象已被不小心删除。 它并没有被删除的错误
我跟踪返回此:
AzureCloudTable_3_0_5.Message_MarkAsRead. Error.Stage.1: MessageID:146751012, BoyID:477296. An error occurred while processing this request. at Microsoft.WindowsAzure.StorageClient.Tasks.Task
1.get_Result() at Microsoft.WindowsAzure.StorageClient.Tasks.Task
1.ExecuteAndWait() at BenderRestfulService_3_0_5.AzureCloudTable.Message_MarkAsRead(Int32 uid) in ...ResourceNotFound
The specified resource does not exist. RequestId:583c59df-fdac-47e4-a03c-7a4bc7d004c9 Time:2011-10-05T16:37:36.7940530Z at System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext()AzureCloudTable_3_0_5.Message_MarkAsRead. Error.Stage.2: MessageID:146751012, BoyID:477296. Message was NOT deleted.
我完全莫名其妙。任何建议非常感谢!
Steven
有两种情况,但是当一个客户端(iPhone应用程序)调用的URL响应下载的消息......所以我想,如果它在被删除的机会的代码只执行一分之一的秒数真的很低。可能可能。但太低以至于不能删除1%的删除 –
还有一些想法:尝试捕获错误并实际测试消息存在。它确实存在吗?另一个要尝试的是为每个逻辑操作使用一个新的tableServiceContext。否则,如果在一次SaveChanges过程中出现故障,下次可能会重试。 (上下文实际上保留了一些关于正在进行的更改的状态。) – smarx
嘿Smarx。我尝试了你的建议,检查是否存在对象*错误说明没有。它*确实存在。我已经重写了我的问题,以包括迄今为止所了解的变化和所有内容。谢谢 –