gpt4 book ai didi

linq - 从 Azure 云表删除时出错 - ResourceNotFound

转载 作者:行者123 更新时间:2023-12-03 18:07:27 24 4
gpt4 key购买 nike

我在从 azure 表中删除对象时遇到间歇性问题。它只影响我大约 1% 的尝试,如果稍后再次进行相同的调用,那么它工作正常,但我很想找出背后的原因!我在谷歌上搜索了一下,发现缺乏关于如何创建非常可靠的删除、插入和更新代码的文档,这令人非常惊讶……这一切似乎有点碰运气,”尝试一下,大多数时候都会有效”

编辑:我将删除此问题中最初的文本,并将其替换为全新的文本,以考虑我已经尝试/建议的内容。

Azure 表会像 SQL Azure 一样遭受间歇性故障吗?如果是这样,我会认为“saveChangesWithRetries”会处理这个问题吗?这是错误的吗?

所以...相当简单的代码,在 Azure Web 角色上每分钟被调用大约 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.Task1.get_Result() at Microsoft.WindowsAzure.StorageClient.Tasks.Task1.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.

我完全困惑了。非常感谢任何建议!!!

史蒂文

最佳答案

此代码是否在多个角色实例或多个应用程序中运行? (也许在您从表中读取实体的时间和尝试删除它的时间之间,该实体正在被另一个进程删除。)

关于linq - 从 Azure 云表删除时出错 - ResourceNotFound,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7590383/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com