首页 > 解决方案 > Azure 表存储 (412) 前提条件失败

问题描述

我已将 GitHub 解决方案用于URLshortener并将其部署在我的 Azure 租户上。现在突然我收到一个错误:

"Exception while executing function: Functions.UrlIngest. 
Microsoft.Azure.WebJobs.Host: Error while handling parameter keyTable after 
function returned:. Microsoft.WindowsAzure.Storage: The remote server 
returned an error: (412) Precondition Failed."

在研究这个问题时,我发现了一个链接,上面写着:

"If the entity's ETag differs from that specified with the update request,
the update operation fails with status code 412 (Precondition Failed). This 
error indicates that the entity has been changed on the server since it was 
retrieved. To resolve this error, retrieve the entity again and reissue the request."

因此,为了解决这个问题,我对 Azure 函数代码进行了以下更改:

try
{
    await tableOut.ExecuteAsync(operation);
}
catch (StorageException ex)
{
    if (ex.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed)
    {
        log.Info("Precondition failure as expected.");

        TableOperation retrieveOperation = TableOperation.Retrieve<NextId>(keyTable.PartitionKey, keyTable.RowKey);

        // Execute the operation.
        TableResult retrievedResult = tableOut.Execute(retrieveOperation);

        int idCount = keyTable.Id;

        // Assign the result to a CustomerEntity object.
        keyTable = (NextId)retrievedResult.Result;

        if (keyTable != null)
        {
            // Change the phone number.
            keyTable.Id = idCount;

            // Create the Replace TableOperation.
            TableOperation updateOperation = TableOperation.Replace(keyTable);

            // Execute the operation.
            tableOut.Execute(updateOperation);

            log.Info("Entity updated.");
        }
        else
        {
            log.Info("Entity could not be retrieved.");
        }
    }
}

它仍然会抛出相同的错误,但是当我检查 Azure 表存储时,它具有正确的值。

谁能帮我解决这个问题?

标签: azureazure-functionsazure-table-storageoptimistic-concurrency

解决方案


此异常的原因(来源):

如果实体的 ETag 与更新请求中指定的不同,更新操作将失败,状态码为 412(前提条件失败)。此错误表明实体在检索后已在服务器上更改。要解决此错误,请再次检索实体并重新发出请求。

如果最后一位作家获胜

一种允许任何更新操作继续进行而不验证自应用程序首次读取数据以来是否有任何其他应用程序更新数据的方法。

对于您的场景来说已经足够好了,您只需要在更新操作之前添加通配符ETag 。就像是:

myEntityToUpdate.ETag = "*";

否则,您必须自己处理不同步的内容 - 例如捕获异常,再次获取更新的数据(使用更新的ETag)并尝试更新更新的数据(使用更新的ETag )。您可以在此处了解有关 Microsoft Azure 存储中的并发性的更多信息。


推荐阅读