2015-04-30 7 views
1

У меня есть бэкэнд для отдыха с Java и Hibernate и им, используя Оптимистическую блокировку с свойством версии. Для контроля параллелизма это свойство версии должно перейти к клиенту и снова к серверу с почтовым запросом. Но, в яваскрипте клиента я потерять контроль над целостностью этого свойства, например:Как обеспечить, чтобы номер версии спящего режима оставался неизменным в javascript-клиенте?

  • Клиент «А» просит свой ресурс 1.
  • Клиент «B» запрашивает тот же ресурс.
  • Сервер отвечает ресурсом 1 версии 1 на оба клиента (в их соответствующих ответах)
  • Клиент «А» изменяет ресурс и создает сообщение для сохранения изменений.
  • Сервер обрабатывает почтовый запрос и Hibernate проверяет номер версии. 1 = 1, чтобы ресурс был изменен.
  • Клиент B играет с javascript и изменяет свойство версии на 2 и делает запрос на отправку. Сервер обрабатывает почтовый запрос, а теперь 2 = 2, поэтому ресурс изменяется и изменения, сделанные клиентом A, теряются.

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

Итак, если это правильный вопрос, как я считаю, как я могу гарантировать, что версия остается неизменной в клиенте?

ответ

1

Лично я бы передумал делать это, так как я не вижу никаких мотивов для клиента, чтобы сделать это, и по определению вы НЕ МОЖЕТЕ контролировать то, что клиент отправляет вашей службе REST.

Однако, если у вас действительно есть бизнес-кейс, то одно полу-решение должно сделать свойство version GUID. Таким образом, вы можете подать только, если у вас есть новейший GUID, который не был бы у клиента B, и это делает процесс версии более сложным, потому что вы не можете просто увеличивать на 1 до тех пор, пока запрос не завершится успешно.

Однако даже там вы не совсем безопасны, так как клиент B теоретически может сделать отдельный запрос на получение обновленного GUID с ресурса, а затем повторно отправить сбойный запрос с обновленным GUID.

Но так как клиент B мог внести изменения в обновленную версию, чтобы вернуть то, что сделал клиент A и добавить свои собственные, это по сути то же самое, что и для этого, и поскольку у них есть полномочия для этого, мы вернулись к спрашивая себя, почему мы в первую очередь беспокоимся об этом случае.

+0

Спасибо @ Briguy37, ответ McCroskey заставил меня подумать, и я понял, что мой вопрос глуп, и вы подтвердили. Я никогда не получу контроль над свойством версии, которое входит в запрос в мое приложение для отдыха. Если я должен защитить свою сущность от обновления, я должен сделать это с моей логической областью. – gabrielgiussi

+0

@gabrielgiussi Как говорится в клише: «Нет такого понятия, как глупый вопрос» :) Хорошо, что у вас есть управление версиями и что вы думаете о том, как улучшить целостность данных. Так держать! – Briguy37

0

Используйте конструктор, который скрывает номер за только для чтения добытчика:

var MyObject = function(version) { 
    var _version = version; 

    this.getVersion = function() { return _version; } 
} 

Или использовать методы получения и установки пары, которая позволяет переменной быть установлен только один раз:

var MyObject = function() { 
    var self = this; 

    var _tripwire = false; 

    var _value = null; 

    self.setValue = function(val) { 
     if (_tripwire==false) 
      _tripwire = true; 
     else 
      throw "Value is read-only"; 

     _value = val; 
    }; 

    self.getValue = function() { 
     return val; 
    } 
}; 

JSFiddle

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

Обратите внимание, что, если вы предпочитаете метод доступа свойства стиля, вы также можете выполнить тот же шаблон проектирования с аксессорами собственности:

function setOnceProp(o, name) { 
    var _value = null; 

    var _tripwire = false; 

    Object.defineProperty(o, name, { 
     get: function() { 
      return _value; 
     }, 
     set: function(newValue) { 
      if (_tripwire==false) 
       _tripwire = true; 
      else 
       throw "Value is read-only"; 

      _value = newValue; 
     }, 
     enumerable: true 
    });  
} 

var MyObject = function() { 
    var self = this; 

    setOnceProp(self, 'value');  
}; 

Это требует, чтобы ваши клиенты используют относительно недавних браузеров.