Атомарность нескольких транзакций базы данных на Heroku - PullRequest
1 голос
/ 03 апреля 2011

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

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

Я знаю, что Heroku использует PostgreSQL, который позволяет мне получить массив блокировок базы данных, но эти блокировки сохраняются только для одной транзакции. Кроме того, я знаком с мьютексами (и pthreads) для синхронизации многопоточных приложений, но я не уверен, будут ли эти соглашения работать в Heroku должным образом, особенно если мой настоящий код приложения работает на нескольких серверах.

EDIT

Я определенно должен объяснить, что я пытаюсь сделать немного больше. Мне нужно сделать два звонка в базу данных. Первый вызов - чтение логического значения. Если это логическое значение истинно, мне нужно выполнить какое-то действие, а если оно ложно, мне нужно сделать что-то еще. Если я читаю TRUE, тогда мне нужно сделать что-то другое (интерфейс с внешними API и т. Д.), И если это удастся, тогда мне нужно установить логическое значение в false. Проблема в том, что я не знаю, как избежать ситуации, когда несколько клиентов читают истину из базы данных, когда, на самом деле, один клиент находится в пути, чтобы написать ложь, но еще не выполнил другие вещи, которые мне нужно сделать раньше писать ложь.

1 Ответ

0 голосов
/ 03 апреля 2011

Вот альтернатива, с которой может работать:

Измените свое логическое поле, чтобы разрешить сохранение переменной с тремя состояниями.(Дата и время тоже могут быть хорошими, я объясню немного.)

Затем кодируйте операции следующим образом:

begin transaction
    read flag
    if true
         set flag to "processing" state
    if false
         perform other activity
commit

Если флаг был true, то онтеперь будет установлен на processing;вызовите внешний API, сделайте все что угодно, и когда результаты станут известны:

begin transaction
    read flag
    if "processing"
        set flag to false
    if true
        warn loudly
    if false
        warn loudly
commit

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...