RavenDB - LoadAsync似乎更改了Etags,导致尝试更新时“尝试使用非当前etag尝试PUT”异常

时间:2016-11-18 11:29:38

标签: c# asp.net-web-api ravendb

由于几天我在尝试更新某些文档时遇到问题,因此不断抛出异常

  

PUT尝试使用非当前的etag

因为每次我们执行LoadAsync来获取特定文档时,它似乎也会更改其etag

我找不到任何类似的案例,我发现最接近的是:Put Attempted on document using non current Etag error

但这是为了创造一个新的对象,并没有得到任何好的答案。

以下是模型:

public class Contact : IDocument
{
    public int Id { get; set; }

    public int UserId { get; set; }

    public int FromUserId { get; set; }

    public Enums.ContactStatus Status { get; set; }

    public string Message { get; set; }

    public DateTime? When { get; set; }

    public Guid? Etag { get; set; }
}

IDocument暴露Guid? Etag

以下是我们尝试进行更新的地方:

[HttpPut]
public async Task<HttpResponseMessage> Put([FromBody] Contact value)
{
    var usercontext = User.GetUserContextSiteRoleFlagsCheck(Request); // Need moderator check.

    using (var asyncsession = documentStore.Store.OpenAsyncSession())
    {
        var canUpdate = usercontext.IsApiAdmin || usercontext.IsModerator || usercontext.SiteUserId == value.FromUserId || usercontext.SiteUserId == value.UserId; // Updatable by either end of the contact
        if (!canUpdate)
        {
            if (value.Id < 1)
            {
                return null;
            }

            var existing = await asyncsession.LoadAsync<Contact>(ItemPath + value.Id);

            if (existing == null)
            {
                return null;
            }
        }

        if (canUpdate)
        {
            try
            {
                asyncsession.Advanced.UseOptimisticConcurrency = true;
                await asyncsession.StoreAsync(value, new Etag(value.Etag.HasValue ? value.Etag.Value.ToString() : Guid.Empty.ToString()), ItemPath + value.Id);
                await asyncsession.SaveChangesAsync();
            }
            catch (ConcurrencyException)
            {
                return new HttpResponseMessage(HttpStatusCode.Conflict);
            }

            if (ConfigSettings.RecordActivities && !usercontext.IsExcludedFromActivities)
            {
                BackgroundTaskManager.Run(() => documentStore.CreateActivity(Enums.ActivityType.Contact, Enums.ActionType.Update, usercontext.APIUserId, usercontext.SiteUserId, value, value.Id));
            }

            var result = await asyncsession.LoadAsync<Contact>(ItemPath + value.Id);
            return Request.CreateResponse(HttpStatusCode.OK, result);
        }
    }

    return new HttpResponseMessage(HttpStatusCode.NotModified);
}

当我们查询API以在同一实体上执行简单的GET时,每次返回不同的Etag时,这里是Get:

[HttpGet]
public async Task<Contact> Get(int id, int userId = 0, bool? reloadcache = false)
{
    var usercontext = User.GetUserContextMinimalCheck(Request);

    using (var asyncsession = documentStore.Store.OpenAsyncSession())
    {
        var result = await asyncsession.LoadAsync<Contact>(ItemPath + id);

        if (result != null)
        {
            if (usercontext.IsApiAdmin || usercontext.IsModerator || (userId > 0 && (result.UserId == userId || result.FromUserId == userId)))
            { 
                return result;
            }
        }
    }

    throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.NoContent, "Not found."));
}

以某种方式,有时,如果你继续查询可能30/40次,在某些时候它会停止更改Etag,我们终于能够更新文档了。 但情况并非总是如此,我们无法弄清楚这里发生了什么。 我注意到的一件事是每次新的Etag似乎都会增加

如果您多次查询Etags的一些示例(来自Postman):

"Etag": "01000000-0000-0027-0000-0000000009a6"
"Etag": "01000000-0000-0027-0000-0000000009ab"
"Etag": "01000000-0000-0027-0000-0000000009b0"
"Etag": "01000000-0000-0027-0000-0000000009b5"
"Etag": "01000000-0000-0027-0000-0000000009ba"
"Etag": "01000000-0000-0027-0000-0000000009bf"
...

我承认我在这里完全迷失了,而我的团队(包括我)对RavenDB来说还是一个新手。

0 个答案:

没有答案