Il semble qu'il existe de nombreuses situations dans lesquelles vous souhaitez stocker des données dans le magasin de données et les enregistrer dans l'index de l'API de recherche. Cependant, si vous ne faites pas attention aux transactions, il est possible que même s'il est stocké dans le magasin de données, il ne soit pas enregistré dans l'index de l'API de recherche (ci-après, l'index signifie l'index de l'API de recherche). Je vais finir.
Par conséquent, considérons une méthode d'enregistrement des données dans le magasin de données et l'index (presque) en même temps.
** 1 méthode n'est pas recommandée **. Cependant, il existe quelques exemples d'utilisation de la méthode 1 (une a été soumise comme réponse dans Stack Overflow, et Ferris 2.2 utilise la méthode 1), je la présente donc pour le moment.
** Non recommandé ** sauf si vous avez une raison spécifique.
class User(ndb.Model):
name = ndb.StringProperty()
def _post_put_hook(self, future):
result = future.get_result()
#Register dans l'index de l'API de recherche ...
post_put_hook est appelé après que l'utilisateur a été placé. Si put échoue, une erreur sera envoyée dans la partie future.get_result (), elle ne sera donc pas enregistrée dans Index. Cependant, il est possible que l'enregistrement de l'utilisateur échoue même si l'enregistrement de l'utilisateur est réussi.
En d'autres termes, cette méthode ne garantit pas la cohérence de la banque de données et de l'index. Si la cohérence ne doit pas être garantie, c'est bien, mais sinon, elle doit être évitée.
user = User(name='Yohei')
@ndb.transactional
def put():
user.put()
doc = search.Document(
doc_id = person.key.urlsafe(),
fields=[
search.TextField(name='name', value=user.name),
],)
index.put(doc)
put()
Cela garantit la cohérence. Cependant, vous devez être prudent dans les exemples suivants.
user = User(name='Yohei')
@ndb.transactional
def put():
user.put()
doc = search.Document(
doc_id = person.key.urlsafe(),
fields=[
search.TextField(name='name', value=user.name),
],)
index.put(doc)
# do something
...
put()
Si une erreur se produit dans la partie faire quelque chose ici, il se peut qu'elle ne soit pas enregistrée dans le magasin de données, mais elle peut être enregistrée dans l'index.
** La file d'attente de tâches peut être traitée de manière transactionnelle. [^ 2-1] ** Par conséquent, si vous ajoutez la tâche «Enregistrer l'API de recherche dans l'index» dans la file d'attente des tâches, vous pouvez garantir la cohérence.
user = User(name='Yohei')
user2 = User(name='Yohei2')
@ndb.transactional(xg=True)
def put():
user.put()
user2.put()
taskqueue.add(
url='/put_to_index',
params={
'key': user.key.urlsafe(),
'name': user.name},
transactional=True,)
taskqueue.add(
url='/put_to_index',
params={
'key': user2.key.urlsafe(),
'name': user2.name},
transactional=True,)
# do something
...
put()
Cela garantit la cohérence, même si faire quelque chose provoque une erreur. Comme dans l'exemple, il est possible de s'inscrire à deux index en même temps. Veuillez noter que vous ne pouvez empiler que jusqu'à 5 files d'attente de tâches transactionnelles. Il doit être évité dans les situations où il y a plusieurs écritures en même temps.
Utilisez 2 ou 3 méthodes. Utilisez correctement selon la situation.
Recommended Posts