2016-05-09 4 views
1

Я использую механизм блокировки, чтобы убедиться, что два параллельных вызова не обновляют ту же строку, что вызывает неожиданное поведение. Поэтому мой код выглядит примерно так: (нет примера с реальным миром)Http Statuscode при ожидании блокировки-освобождения занимает много времени?

public class UserController { 
    public ActionResult AddReputation(int id, int repAmount) { 
    int lockWait=0; 
    bool alreadyLocked=true; 
    while (alreadyLocked) { 
     alreadyLocked=GetLockForUser(id); 
     Thread.Wait(1000); 
     lockWait++; 
     if (lockWait>10) { 
      return new HttpStatus(xxx); 
     } 
    } 
    SetlockForUser(id); 
    AddUserRep(id,repAmount); 
    return new Content("Well Done"); 
    } 
    } 

So. Если через 10 секунд блокировка все еще существует, я хочу сообщить вызывающему абоненту «Повторите попытку позже, кто-то еще просто сохранит данные для этого пользователя».

Какой был бы лучший HTTP-код в REST-API для этого? 409 Conflict? или 423 Locked?

Примечание: это не SQL-DB. У меня нет реальных механизмов транзакций, которые я могу использовать. Поэтому я должен реализовать свой собственный механизм блокировки.

+0

Более здравый способ решить эту проблему - использовать etags и If-Match. – Evert

+0

@Evert Серверу все равно придется получить блокировку, прежде чем он сможет спокойно оценить «If-Match». Так что это все равно может закончиться. Но я согласен, что PUT + 'If-Match' может быть хорошей идеей для чего-то, называемого AddReputation. –

+0

Немного OT, но: Я думаю 'while (! GetLockForUser (id)) {' делает для более чистого (и безопасного) кода. Также: Срок действия замков истекает через некоторое время? Я не вижу механизма выпуска. Блокировка 'GetLockForUser (id)'? Я также чувствую, что 1000 мс слишком много для задержки. – DaSourcerer

ответ

2

Вы должны задать себе вопрос: что будет делать клиент в этой ситуации?

Из вашего описания это звучит как единственный выбор клиента - это подождать и повторить попытку позже. Так 503 (Service Unavailable) кажется хорошей пригонки:

указывает на то, что сервер не может обработать запрос из-за временной перегрузки или планового технического обслуживания, которая, вероятно, будет облегчено после некоторой задержки

Кроме того, общий номер 500 (Internal Server Error) всегда к вашим услугам.

423 (Заблокировано) может быть или не быть подходящим. Он был разработан как часть WebDAV’s locking mechanisms, где клиенты явно блокируют и разблокируют ресурсы. Как правило, клиенты с большей вероятностью понимают ошибку 503 (очень распространенную в дикой природе), чем ошибку 423 (редко встречающаяся вне WebDAV): 423, скорее всего, будет рассматриваться как общий client error, что может быть не очень полезно. При этом the definition of 423 itself не требует блокировки WebDAV. Если вы хотите отличить эту ситуацию от чего-то вроде простоя сервера (что приведет к 503), тогда может работать 423.

409 (Conflict) делает не кажется хорошей пригонки:

Этот код используется в ситуациях, когда пользователь может быть в состоянии разрешить конфликт и повторно отправить запрос.

+1

Я не так уверен в 423, поскольку он в значительной степени связан с механизмом блокировки WebDAV: IMHO он не так сильно предназначен для использования с помощью общих реализаций блокировки. Но 503 действительно идеально подходит. – DaSourcerer

Смежные вопросы