java: условия гонки - есть ли способ убедиться, что несколько строк кода будут выполняться вместе?

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

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

Благодарность

Обновить

У меня два сервера.

  1. апач томкэт 6
  2. red5 v0.9 (бесплатный сервер для потоковой передачи и обмена данными на базе Java)

Я пишу игровое приложение для Facebook.

сама игра написана в Adobe Flash Builder 2.

сама игра будет обслуживаться с помощью сервера red5. проблема в том, что red5 не получает заголовки запроса и ответа и из-за этого не может получить информацию о сеансе, чтобы использовать ее для получения информации из facebook.

чтобы решить проблему, когда пользователь подключается к серверу tomcat, эта страница проверяет сеанс на наличие информации, связанной с facebook, и использует tinyFBClient для подключения к facebook и для сохранения информации в базе данных mysql (данные пользователя), чтобы убедиться, что это тот же пользователь — это пользователь, который собирается подключиться к red5.

после создания токена. страница tomcat отображает элемент HTML объекта, чтобы показать соответствующий файл SWF (файл игры). страница tomcat передает токен в этот SWF-файл. как только файл SWF загружается, он берет этот токен и использует его для подключения к red5 и для получения информации о пользователе.

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


person ufk    schedule 08.02.2010    source источник


Ответы (5)


Вы можете использовать объект Lock.

Использование объектов Lock имеет преимущества перед более примитивными синхронизированными блоками и методами.

person kgiannakakis    schedule 08.02.2010

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

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

person danben    schedule 08.02.2010

Похоже, вам нужен синхронизированный метод/блок:

См. здесь, например (синхронный метод)

http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html

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

person monojohnny    schedule 08.02.2010

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

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

person Jay    schedule 08.02.2010
comment
Я обновил основной пост, чтобы объяснить, почему мне нужно использовать токены. Благодарность - person ufk; 08.02.2010

Вы говорите, что «удаляете токен из БД». Является ли база данных базой данных SQL? Если это так, вы можете использовать транзакцию, чтобы избежать состояния гонки. Это будет выглядеть примерно так:

  1. Создайте уникальный идентификатор сеанса, например. UUID sessionID = UUID.randomUUID();
  2. Начать транзакцию
  3. Удалите все токены из БД, которые совпадают с тем, что указан в запросе, например,
    DELETE FROM Tokens WHERE TokenID = ‹requested-token›
  4. Получить затронутое количество строк
  5. Если затронутое число строк равно 1, то маркер был действительным. Создайте сеанс, например
    ВСТАВЬТЕ В ЗНАЧЕНИЯ сеанса (sessionUUID, userID, loginTime, ...)
  6. Зафиксировать транзакцию

Теперь, если вход в систему был успешным (т. е. количество затронутых строк было ровно 1), отправьте клиенту файл cookie, содержащий идентификатор сеанса.

person finnw    schedule 08.02.2010
comment
Я использую Myisam db и, насколько мне известно, он не поддерживает транзакции. - person ufk; 08.02.2010