2015-10-14 4 views
0

У меня есть ситуация в моем java, основанном на весне веб-приложении. Мой сервер генерирует купоны (число, смешанное с алфавитами, все случайные, но уникальные), каждый купон можно применять или использовать только один и только при регистрации в клиенте. Они отображаются на переднем конце всем пользователям, которые затем принимаются/выбираются клиентами. Но один раз, когда один клиент получает его, он присваивается ему и недоступен кому-либо еще.Webapp java synchronized object aquire

Я пытался сделать синхронизацию кода блока, который проверяет, если купон уже применяется/воспользовалось, он работал, но, случаи, как, когда два пользователя нажмите воспользоваться его точно в то же время, он выходит из строя (получить выделяется как)

Пожалуйста, помогите.

ответ

1

Не используйте для этого синхронизацию. Вы можете сохранить состояние купонов в базе данных и работать с этими данными в транзакции БД, используя блокировки. Итак:

  • Пользователь пытается купон, вы получите ID
  • начать транзакцию БД, получить купон строки из него, и зафиксируйте его
  • Делайте то, что вам нужно, то аннулирует купон
  • Завершение транзакции базы данных, освободить фиксатор

в базе данных не necessarly должны быть автономным RDMS, в простом случае, даже SQLite достаточно. В любом случае, DBs, безусловно, справляются с условиями гонки, чем вы (или большинство из нас).

0

Если вы предпочитаете избегать транзакций базы данных, вы можете использовать Набор со всеми сгенерированными купонами и набор, ссылающийся только на доступные купоны. Когда пользователь выбирает купон в блоке синхронизации, удалите купон из доступных. Затем второй пользователь не может его получить

0

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

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

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

+0

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