2014-09-06 2 views
0

Я запускаю веб-службу Java внутри Tomcat.Предотвращение веб-службы Java от одновременной модификации записи

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

Существует только один метод обслуживания, который пытается выполнить запись пользователя, но он много обрабатывает и может занять некоторое время. Весьма вероятно, что более одного из этих приложений Rails попытаются вносить изменения одному и тому же пользователю, пока предыдущий вызов все еще обрабатывается.

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

Я думал об использовании набора для хранения идентификаторов пользователей в настоящее время, а затем для синхронизации с объектом коллекции. Первый, чтобы иметь возможность добавлять идентификатор пользователя в коллекцию, обрабатывается, а тот, который обнаруживает идентификатор пользователя уже в коллекции, возвращает, скажем, ошибку 409 Conflict.

Set<String> activeUserIds = new HashSet<String>(); 

// annotations, mappings, etc. 
public ResponseEntity<String> putUser(User user) { 

    boolean canProcess; 
    synchoronize(activeUserIds) { 
     canProcess = activeUserIds.add(user.getId()) { 
    } 

    if (!canProcess) { 
     return new ResponseEntity<String>("user already being modified", Status.CONFLICT); 
    } 

    // perform service activity 

    synchoronize(activeUserIds) { 
     activeUserIds.remove(user.getId()) { 
    } 

} 

Возможно ли это? Я не нашел ничего встроенного в Tomcat или Spring MVC, который автоматически обрабатывал бы такое поведение, но есть ли уже встроенное решение, о котором я не знаю?

+0

Любого решение, которое использует операцию параллельности Java (только) может работать только тогда, когда ваше приложение не кластерируется на нескольких машинах/JVM. Какое фоновое хранилище вы используете для записи пользователя? Если вы используете базу данных SQL, вы можете заблокировать строку в начале кода обработки запроса. –

ответ

0

Я думаю, что решение, которое вы предложили, должно работать, если у вас есть один экземпляр веб-браузера (как указал Эрвин в комментариях). Я не знаю ни одного встроенного решения, выполняющего именно это.

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

Set<String> activeUserIds = Collections.synchronizedSet(new HashSet<String>()); 
Смежные вопросы