В моем приложении на базе GAE есть модель, которая обновляется довольно часто. И в некоторых случаях бывает, что одна и та же сущность обновляется почти одновременно. Функциональность обновления сущностей в приложении работает следующим образом:
- Пользователь вводит идентификатор и другие свойства объекта, которые должны быть обновлены.
- Получить сущность из БД по этому идентификатору (чтобы убедиться, что идентификатор действителен).
- Выполните кучу проверок свойств, которые будут обновлены (например, если свойство group_id обновляется, убедитесь, что группа присутствует в БД с этим идентификатором, а идентификатор целочисленный.)
- После проверки, вызовите put () для объекта, который был получен на шаге №2.
Поскольку, как я упоминал, одна и та же сущность может обновляться несколько раз практически одновременно, поэтому я столкнулся с проблемой классических условий гонки. то есть, скажем, 2 вызова обновления были сделаны последовательно, в первом объекте вызова был получен объект и выполнялись проверки, но в то же время при втором вызове он извлекает то же самое и обновляет свои свойства. Второй вызов также выполняет put () и обновляет сущность в БД. ЗАМЕТЬТЕ, что первый вызов еще не был завершен (из-за некоторой задержки), он завершается сейчас и вызывает put () и обновляет объект в БД.
Конечный результат в БД будет отключен при первом вызове обновления, но ожидаемый результат был при втором вызове!
Я исследовал GAE по этому поводу и нашел предварительно поставленные крючки. Я думаю, что могу использовать «обновленные» временные метки, чтобы решить эту проблему, то есть убедиться, что второй вызов обновляет только сущность после первого вызова. Но я хочу использовать лучший подход, например, некоторые БД (как в AWS) предоставляют теги для каждой строки БД, и мы можем попросить саму БД проверить этот тег перед фактическим размещением записи. Мне любопытно, как в GAE есть способ сделать это. то есть попросить БД сделать условный put () вместо ручного перехвата pre_put?