Es scheint, dass es einige Situationen gibt, in denen Sie Daten im Datenspeicher speichern und im Index der Such-API registrieren möchten. Wenn Sie jedoch bei Transaktionen nicht vorsichtig sind, ist es möglich, dass sie, obwohl sie im Datenspeicher gespeichert sind, nicht im Such-API-Index registriert sind (im Folgenden bedeutet Index den Such-API-Index). Ich werde am Ende.
Betrachten wir daher eine Methode zum (fast) gleichzeitigen Registrieren von Daten im Datenspeicher und im Index.
** 1 Methode wird nicht empfohlen **. Es gibt jedoch einige Beispiele für die Verwendung von Methode 1 (eines wurde als Antwort in Stack Overflow eingereicht, und Ferris 2.2 verwendet Methode 1), daher stelle ich es vorerst vor.
** Nicht empfohlen **, es sei denn, Sie haben einen bestimmten Grund.
class User(ndb.Model):
name = ndb.StringProperty()
def _post_put_hook(self, future):
result = future.get_result()
...
post_put_hook wird aufgerufen, nachdem User gesetzt wurde. Wenn put fehlschlägt, wird im Teil future.get_result () ein Fehler gesendet, sodass er nicht im Index registriert wird. Es besteht jedoch die Möglichkeit, dass die Registrierung des Benutzers fehlschlägt, obwohl die Registrierung des Benutzers erfolgreich ist.
Mit anderen Worten, diese Methode garantiert nicht die Konsistenz von Datenspeicher und Index. Wenn die Konsistenz nicht garantiert werden muss, ist dies in Ordnung. Wenn nicht, sollte dies vermieden werden.
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()
Dies garantiert Konsistenz. In den folgenden Beispielen müssen Sie jedoch vorsichtig sein.
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()
Wenn hier ein Fehler im Teil "etwas tun" auftritt, wird er möglicherweise nicht im Datenspeicher registriert, aber möglicherweise im Index.
** Task Queue kann transaktional verarbeitet werden. [^ 2-1] ** Wenn Sie daher die Aufgabe "Such-API zum Index registrieren" in der Aufgabenwarteschlange hinzufügen, können Sie die Konsistenz garantieren.
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()
Dies garantiert Konsistenz, auch wenn etwas einen Fehler verursacht. Wie im Beispiel ist es möglich, sich gleichzeitig in zwei Indizes zu registrieren. Bitte beachten Sie, dass Sie nur bis zu 5 Transaktions-Task-Warteschlangen stapeln können. Dies sollte in Situationen vermieden werden, in denen viele Schreibvorgänge gleichzeitig ausgeführt werden.
Verwenden Sie 2 oder 3 Methoden. Je nach Situation richtig verwenden.