Двойной щелчок на двойном разрешении? - PullRequest
1 голос
/ 03 октября 2008

У члена команды возникла проблема со старой внутренней системой, когда пользователь, дважды щелкнув ссылку на веб-странице, может вызвать отправку двух запросов из браузера, что приведет к двум вставкам базы данных одной записи в состоянии гонки; последний из них не работает с нарушением первичного ключа. Несколько решений и взломов были предложены и обсуждены:

  1. Используйте Javascript на веб-странице, чтобы уменьшить второй щелчок, отключив ссылку на первый щелчок. Это быстрый и простой способ уменьшить возникновение проблемы, но не полностью устранить ее.

  2. Обернуть выполнение запроса на стороне сервера в транзакции. Эта операция считалась слишком дорогой из-за нагрузки на сервер и уровней блокировки в рассматриваемой таблице.

  3. Перехватить исключение первичного ключа, вызванное неудачной вставкой, идентифицировать его как таковое и использовать. Это имеет недостатки: (а) блокировка поставщика, необходимость знать нюансы исключений, характерных для базы данных, и (б) возможность не регистрировать / обрабатывать допустимые сбои базы данных.

  4. Расширение # 3 путем попытки обновления записи в случае сбоя вставки и проверки результата обновления, чтобы убедиться, что он возвращает 1 затронутую запись.

Есть другие варианты, которые не были рассмотрены? Есть ли плюсы и минусы представленных вариантов, которые были упущены? Что является меньшим из всех зол?

Ответы [ 5 ]

5 голосов
/ 03 октября 2008

Поместите уникальный идентификатор на страницу в скрытом поле. Принимайте только один ответ с заданным уникальным идентификатором.

2 голосов
/ 03 октября 2008

Похоже, вы, возможно, неправильно используете запрос GET для изменения состояния сервера (хотя это не всегда так). Хотя это может не подходить для вашей ситуации, следует указать, что вам следует рассмотреть возможность преобразования ссылки в форму POST.

1 голос
/ 19 ноября 2008

Вам необходимо реализовать шаблон токена синхронизатора.

Как это работает: значение (токен) генерируется на сервере для каждого запроса. Этот же токен должен быть включен в вашу форму. После получения запроса токен сервера и токен клиента сравниваются, и если они совпадают, вы можете продолжить добавление своей записи. Затем токен на стороне сервера регенерируется, поэтому последующие запросы, содержащие старый токен, не будут выполнены.

Есть более подробное объяснение о том, как на полпути вниз эта страница .

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

0 голосов
/ 19 ноября 2008

REF Необходимо реализовать шаблон токена синхронизатора.

Это для Javascript / HTML, а не JAVA

0 голосов
/ 03 октября 2008

Кажется, вы уже ответили на свой вопрос; Кажется, # 1 - единственный жизнеспособный вариант.

В противном случае вы действительно должны выполнить все три шага - целостность данных должна обрабатываться на уровне базы данных, но дополнительные проверки (например, явная транзакция) в коде во избежание обращения к базе данных могут быть хороши для производительности. 1003 *

...