2012-03-17 1 views
1

Я пытаюсь реализовать активный шаблон записи с использованием Java/JDBC и MySQL, а также оптимистичную блокировку для обработки параллелизма.Активный шаблон записи с оптимистичной блокировкой - прочитайте перед обновлением и сохраните версию в приложении?

Теперь у меня есть поле «version_number» для всех записей в таблице, которые увеличиваются после каждого обновления.

Там кажется 2 стратегии для реализации этого:

  1. Приложения, когда он запрашивает данные, которые он также хранит соответствующий номер версии каждый из объектов (т.е. записи). При обновлении номер версии «отправляется вниз» на уровень данных, который используется в UPDATE ... SET ... WHERE запрос для оптимистической блокировки
  2. Приложение НЕ хранит номер версии, но только некоторые части объект (в отличие от целой строки данных). Чтобы оптимистичная блокировка была успешной, для слоя данных (активной записи) потребуется сначала извлечь «строку» из БД, получить номер версии и затем запустить тот же UPDATE ... SET ... WHERE запрос для обновления записи.

В первом есть «первая выборка», а затем обновление. В последнем случае у вас есть «первая выборка», но также a fetch перед обновление.

Вопрос в следующем: по дизайну, который лучше подходит? Все в порядке/безопасно/правильно, чтобы все данные, включая номер версии, были сохранены в интерфейсе веб-приложения (Javascript/HTML)? Или лучше взять удар производительности чтения перед обновлением?

Есть ли «правильный путь» для реализации этого дизайна? Я не уверен, как текущие реализации активной записи справляются с этим (Ruby, Play, ActiveJDBC и т. Д.). Если я должен реализовать это «raw» в JDBC, то в этом случае правильное дизайнерское решение?

ответ

1

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

С первым подходом вы оптимистично блокируете строку для всего «времени мысли» пользователя. Если Пользователь 1 загружает экран, то Пользователь 2 вносит изменения, изменения пользователя 1 не удаются, и они будут видеть ошибку, с которой они смотрели устаревшие данные.

При втором подходе вы защищаете только от чередования записей между конкурирующими потоками запросов. Пользователь 1 может загружать страницу, затем Пользователь 2 вносит изменения, а затем, когда Пользователь 1 попадает в submit, их изменения будут проходить и сбрасывать изменения User 2. Пользователь 1 мог принять решение на основе устаревшей информации и никогда не знать.

Это вопрос того, какое поведение вы хотите для своих бизнес-правил, а не то, что технически «правильно». они оба действительны, они делают разные вещи.

+0

Я думаю, что есть путаница здесь - я не запираю строку за все время думает, что и не произойдет потерянное обновление! Я просто не сделал явного факта, что я бы выбрал исключение в случае, если обновление не удалось и сообщит пользователю! Я не уверен, что любой из двух сценариев, которые вы упомянули, даже произойдет? – PhD

+0

В сценарии 1 вы оптимистично блокируете строку для размышления.Вы знаете, что такое номер версии, когда пользователь начал думать, и вы убедитесь, что это то же самое, когда они сделаны. В сценарии 2 вы проверяете номер версии только в конце, когда они отправляются. Это может отличаться от того, когда они начали думать, следовательно, потеряли обновление. – Affe

+0

tl; dr option 1 - правильный способ сделать «нормальную» оптимистичную блокировку. вариант 2 приводит к ситуации параллелизма с последними в выигрышах и действительно проверяет только потоки потоков на сервере, а не пользовательские мыслительные чередования. – Affe

1

ActiveJDBC реализует версию 1. Начиная с версией 2, вы можете ввести условия гонки