Concurent Доступ к хранилищу данных в движке приложения - PullRequest
1 голос
/ 01 декабря 2010

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

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

Является ли db.run_in_transaction () правильным / наилучшим способом сделать это

в следующем коде я пытаюсь создать новый уникальный объект со следующим кодом

def txn(charmer=None):
    new = None
    key = my_magic() + random_part()
    sk = Snake.get_by_name(key)
    if not sk:
       new = Snake(key_name=key, charmer= charmer)
       new.put()
    return new
db.run_in_transaction(txn, charmer) 

Ответы [ 2 ]

4 голосов
/ 01 декабря 2010

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

Похоже, вы уже просмотрели документацию транзакции .Существует также более подробное описание .

Проверьте документы (в частности, эквивалентный код) на Model.get_or_insert, он точно отвечает на ваш вопрос:

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

0 голосов
/ 01 декабря 2010

То, что вы сделали, правильно и как бы дублирует Model.get_or_insert , как уже объяснил Роберт.

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

...