Конфликт базы данных GAE Push Queue во время запроса к хранилищу данных

Резюме У меня возникла проблема, из-за которой база данных записывает из моей очереди задач (примерно 60 задач со скоростью 10/с) каким-то образом перезаписывается/отбрасывается во время параллельной работы с базой данных чтение одних и тех же данных. Я объясню, как это работает. Каждой задаче в очереди задач назначается уникальный идентификатор для определенного объекта хранилища данных модели. Если я запускаю запрос к индексированному хранилищу данных в модели и циклически перебираю объекты во время выполнения очереди задач, я ожидаю, что некоторые объекты будут обработаны очередью задач (т. е. присвоен идентификатор), а другие еще предстоит осуществить. К сожалению, то, что, похоже, происходит во время цикла запроса, объекты, которые уже были обработаны (т. - они были прооперированы.

Почему это происходит? Мне нужно иметь возможность читать состояние моих данных, не влияя на операцию записи очереди задач в фоновом режиме. Я подумал, что это может быть проблема с кэшированием, поэтому я попытался применить к запросу use_cache=False и use_memcache=False, но это не решило проблему. Любая помощь будет оценена по достоинству.

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


person Roy Lindsay    schedule 18.10.2019    source источник


Ответы (1)


Обычно это указывает на то, что операции записи в сущности не выполняются в транзакциях. Транзакции могут обнаруживать такие одновременные операции записи (и чтения!) и повторять их, гарантируя, что данные останутся согласованными.

Вы также должны знать, что запросы (если они не являются запросами-предками) в конечном счете непротиворечивы, то есть их результаты немного «отстают» от фактической информации хранилища данных (проходит некоторое время с момента обновления информации хранилища данных до появления соответствующих индексов). используемые запросами, обновляются соответствующим образом). Поэтому при обработке сущностей из результатов запроса вы также должны транзакционно проверять их содержимое. Лично я предпочитаю делать запросы keys_only, а затем получать объекты по ключу поиски, которые всегда непротиворечивы (конечно, также в транзакциях, если я намерен обновить сущности и при чтении, если это необходимо).

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

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

person Dan Cornilescu    schedule 19.10.2019
comment
Спасибо за ваш ответ, это работает для меня, следует отметить, что реализация предков базы данных требовалась, прежде чем я мог реализовать решение для транзакций (чтения). Без реализации предков мой единственный вид сущности рассматривался как отдельные группы сущностей для каждой сущности, что приводило к ошибке ограничения группы сущностей. stackoverflow.com/questions/8251594/ - person Roy Lindsay; 21.10.2019
comment
Проверьте API, есть возможность разрешить межгрупповые транзакции (но следите за максимальным количеством групп сущностей на лимит транзакции). Структурируйте свои транзакции, чтобы свести к минимуму количество сущностей, затронутых внутри каждой из них, чтобы не превысить этот предел и уменьшить вероятность разногласий (см. Также stackoverflow.com/a/45496048/4495081). Например, не обновляйте несколько сущностей, если только их абсолютно не нужно обновлять вместе, а не потому, что их легко повторять. - person Dan Cornilescu; 21.10.2019