Параметры синхронизации Java для предотвращения дублирования заказов (файл, блокировка БД?) - PullRequest
1 голос
/ 20 июня 2011

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

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

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

Все заказы имеют уникальный длинный идентификатор, поэтому я могу использовать его для синхронизации. Что было бы лучшим способом сделать это? Я мог бы потенциально создать файл для каждого идентификатора или сделать что-нибудь более необычное с областью файла. Однако у меня нет большого опыта с блокировкой файлов, поэтому, если есть лучший вариант, я хотел бы услышать это. Любые примеры кода очень помогут.

1 Ответ

4 голосов
/ 20 июня 2011

Если у вас уже есть уникальный длинный идентификатор, с вами не может случиться ничего лучше, чем простая таблица базы данных с назначенными вручную первичными ключами.Каждая СУБД (а также базы данных NoSQL со значением ключа) будет эффективно и эффективно обнаруживать конфликты первичных ключей.В основном это:

  1. Начать транзакцию
  2. INSERT INTO orders VALUES (your_unique_id)
  3. Фиксация

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

Если вы действительно хотите избежать баз данных (не могли бы вы подробнее рассказать, почему?), вы можете:

  1. Используйте блокировку файлов (неприятную и не масштабируемую), не делайте этого.

  2. Блокировка в памяти с кластеризацией (с Терракота это похоже на работу с обычной boolean, который магически кластеризован)

  3. Очередь запросов и наличие только одного потребителя.

Использование JMS и однопоточного потребителя выглядит многообещающе, однаковам все равно придется обнаруживать дубликаты (но, по крайней мере, вы избегаете одновременного размещения заказов), и это может быть ужасно медленным ...

...