2013-04-12 3 views
0

Я работаю над небольшим проектом в Google App Engine, пытаясь реализовать сайт, который позволяет участникам покупать и продавать поддельные товары, подобно фондовому рынку, где система покажет спреды BID/ASK в режиме реального времени.Как реализовать масштабируемое и безопасное обновление типа банка/кросс-кода

Как простой пример:

  • А места продавца и для того, чтобы продать 10 Коробки для 8,00 (Order 1)
  • А Покупатель места, то заказ на покупку 5 коробок до 9,00 (порядка 2)

При размещении второго заказа системе необходимо выполнить несколько задач, все из которых будут выполняться успешно.

  • Возьмите средства (8,00 х 5) для оплаты коробок от покупателя и дать им Продавцу
  • Возьмите ящики (5) от Продавца и дать им обновления Покупатель
  • заказы в комплекте (OID 2) или обновления, частично заполненный (OID 1), так что они не могут быть в два раза соответствует
  • Возьмите плату от каждого из участников и добавить его к учетной записи системы

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

Кроме того, моя «Книга заказов» и механизм согласования заказов теперь имеют одну резьбу (с использованием взаимных блокировок для блокировки). Это, похоже, противоречит целям использования App Engine, но я не уверен, что вижу способ вокруг него.

So (наконец) - Мои вопросы:

  • Есть ли лучшая практика при использовании App Engine, где есть несколько шагов, которые все зависят от каждого шага завершающего правильно?
  • Есть ли у кого-нибудь какие-либо предложения, как сделать так, чтобы книга заказов была многопоточной, или если она остается однопоточной - есть ли наилучшая практика, чтобы этот блок ядра не использовал использование сайта, поскольку он масштабируется ? Я подумал о том, чтобы использовать задачи для очереди в порядке добавления/обновления/отмены, чтобы сохранить книгу отдельно от прямого ввода участника.

Благодарим вас, я с нетерпением жду вашей помощи!

+0

Также, чтобы уточнить - мое понимание транзакций в App Engine заключается в том, что они ограничены одной группой сущностей, но, может быть, я ошибаюсь, и просто выполнение вышеуказанного в транзакции - это все, что мне нужно? –

+0

Я бы прочитал эту статью Ником Джонсоном http://blog.notdot.net/2009/9/Distributed-Transactions-on-App-Engine –

+0

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

ответ

1

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

  1. Положите средства в условное депонирование, чтобы любые поручения, которые могут быть очищены.
  2. Бросьте заказы на покупку, когда вы попытаетесь очистить их, если средства недоступны.

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

Вы можете упорядочить заказы по времени (например, paced_at = db.DateTimeProperty (auto_now_add = True)). Если два ордера имеют одно и то же время, то используйте что-то (желательно что-то справедливое и детерминированное), чтобы сломать галстук. Хеш (для справедливости) числового идентификатора (для детерминизма), возможно, не является плохим выбором здесь.

App Engine по своей сути многопоточен в том смысле, что приложение может иметь много параллельных экземпляров (экземпляры не обязательно являются потоками одного и того же процесса). Экземпляры создаются автоматически, и в настоящее время нет возможности ограничить количество экземпляров в 1. Если состояние вашего приложения находится в Datastore (в отличие от локальной памяти, memecache или где-то еще), и ваши транзакции верны, тогда ваше приложение будет многопоточным «бесплатно». Конечно, правильные транзакции не являются тривиальными.

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

+0

Это, по сути, то, что я делаю - с использованием мьютекса Memcache для блокировки книги во время добавления или торговли, перемещения средств в escrow/hold во время добавления, а затем с использованием транзакций XG для обновления 4 одновременных задач, которые необходимо выполнить во время торговли - две передачи и два обновления заказа. –

+0

Что подразумевается под мьютексом Memcache? Я не думал об этом очень сильно, но я не думаю, что такое возможно, esp, поскольку Memcache разрешено очищать все ваши данные в любое время без причины. – allyourcode

0

Для других, которые натыкаются на это -

кажется, что Cross-Group Сделки теперь можно в Google App Engine:

https://developers.google.com/appengine/docs/python/datastore/transactions#Using_Cross_Group_Transactions

Это означает, что вы можете, в пределах одной транзакции одновременно читать, выполнять логику, а затем записывать сразу несколько объектов.

Я считаю, что это решает первый вопрос, который я предложил в своем вопросе.

Второй вопрос - есть ли способ заказать книгу заказов, которая не является одиночной, все еще открыта.

Спасибо!

Смежные вопросы