简体   繁体   English

可以避免使用TableController进行乐观并发检查

[英]Optimistic concurrency checks using TableController can be avoided

I'm just testing with the sample ASP.NET Mobile App Web API through Visual Studio and have some questions regarding the concurrency checks. 我只是通过Visual Studio使用示例ASP.NET Mobile App Web API进行测试,并且对并发检查有一些疑问。

The TableController<T> requires updates to be submitted using the following: TableController<T>要求使用以下内容提交更新:

protected virtual Task<TData> UpdateAsync(string id, Delta<TData> patch)

ie it takes a Delta<T> of the changes. 即,它需要更改的Delta<T> There is no "overwrite" update. 没有“覆盖”更新。

The sample entity in the project is TodoItem which derives from EntityData which implements a bunch of standard properties, one of which is the Version property, which as I understand Entity Framework will detect as the concurrency property to check versions before update. 项目中的示例实体是TodoItem ,它是从EntityData派生的,该实体实现了一堆标准属性,其中一个是Version属性,据我所知,Entity Framework将在更新之前将其作为并发属性来检查版本。

I've created a test client to Get a TodoItem , change the Text property and then submit it as an update. 我已经创建了一个测试客户端来Get TodoItem ,更改Text属性,然后将其作为更新提交。

I have found that if I just send the the Delta containing the updated Text property (along with the Id in the URL, of course) then I can just update as much as I want and overwrite and changes that may have occurred in the meantime . 我发现,如果我只发送包含更新的Text属性的Delta(当然,还有URL中的Id ),那么我可以随心所欲地进行更新,并覆盖在此期间可能发生的更改

If I change the Delta to include the updated Text property and the Version of the TodoItem when I fetched it, then if I make my Patch request I get a 409 error if there have been changes in the meantime, as expected. 如果我在获取它时更改了Delta以包括更新的Text属性 TodoItemVersion ,则如果我进行了Patch请求,并且在此期间发生了预期的变化,则会收到409错误。

Can anyone tell me why this Delta pattern seems to allow you to circumvent the concurrency checks, and if there is any way to ensure that the checks always happen? 谁能告诉我为什么这种Delta模式似乎可以绕开并发检查,以及是否有任何方法可以确保检查始终进行?

It appears that it is perfectly possible to circumvent the concurrency checks, but it is based upon the Request Header "If-Match". 看来,这完全可以围绕并发检查,但它是基于请求头“如果-匹配”。

See https://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server.Tables/TableControllerOfData.cs#L332 参见https://github.com/Azure/azure-mobile-apps-net-server/blob/master/src/Microsoft.Azure.Mobile.Server.Tables/TableControllerOfData.cs#L332

byte[] version = this.Request.GetVersionFromIfMatch();
if (version != null)
{
    if (!patch.TrySetPropertyValue(TableUtils.VersionPropertyName, version))
    {
        string error = TResources.TableController_CouldNotSetVersion.FormatForUser(TableUtils.VersionPropertyName, version);
        this.traceWriter.Error(error, this.Request, ServiceLogCategories.TableControllers);
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, error));
    }
}

So if there is no "If-Match" Version then the concurrency checks do not take place. 因此,如果没有“ If-Match”版本,则不会进行并发检查。

If you are using the Azure Mobile App Client SDK then the "Version" property of your entity is "raised up" and put in the "If-Match" header for you. 如果您使用的是Azure移动应用程序客户端SDK,则将“提升”实体的“版本”属性,并为您放置“如果匹配”标头。 See https://docs.microsoft.com/en-gb/azure/app-service-mobile/app-service-mobile-dotnet-how-to-use-client-library#optimisticconcurrency 请参阅https://docs.microsoft.com/zh-CN/azure/app-service-mobile/app-service-mobile-dotnet-how-to-use-client-library#optimisticconcurrency

So if you want to force the concurrency checks, you need to ensure that "If-Match" is set. 因此,如果要强制进行并发检查,则需要确保设置了“ If-Match”。 ie

// PATCH tables/TodoItem/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<TodoItem> PatchTodoItem(string id, Delta<TodoItem> patch)
{
    CheckUpdateForPrecondition();
    return UpdateAsync(id, patch);
}

private void CheckUpdateForPrecondition()
{
    if (!Request.Headers.Contains("If-Match"))
        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            Content = new StringContent("A pre-condition version must be supplied with Update (Header: If-Match).")
        });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM