2016-04-09 5 views
0

Ich habe eine App Engine-Anwendung (Java), mit der zwei Android-Geräte eine Verbindung herstellen. Das App Engine-Backend bietet eine Funktion 'setUsername', mit der Clients ihren Benutzernamen festlegen können.App Engine setzt Programmausführung fort, obwohl BadRequestException geworfen wird

public void setUsername(@Named("username") String username, User oauthUser) throws OAuthRequestException, BadRequestException { 
    UserRecord user = OAuthTools.getUser(oauthUser); 
    updateUsername(user, username); 
    ofy().save().entity(user); 
} 

private void updateUsername(UserRecord user, String username) throws BadRequestException { 
    user.name = username; 
//Search for a user that already has the desired username. Note that the entity is NOT being saved in this method. 
    UserRecord existingUser = ofy().load().type(UserRecord.class).filter("normalizedName", user.normalizedName).first().now(); 
    if(existingUser != null && existingUser.id != user.id) throw new BadRequestException("username taken"); 
} 

Das Problem ist, wie folgt: Nachdem ich durch den Aufruf setUsername einige Benutzernamen mit dem ersten Android-Client festgelegt (zum Beispiel ‚aaaa‘), ich versuche, den gleichen Benutzernamen, um den zweiten Android-Client (nicht gleichzeitig sind mindestens 10 Sekunden zwischen den Anrufen verstrichen). Das Back-End löst dann korrekt eine BadRequestException mit der Nachricht "username taken" aus, schreibt aber immer noch den identischen Benutzernamen an den zweiten Benutzer in der Datenbank, d. H. Beide Benutzer haben den Benutzernamen 'aaaa' nach diesem Aufruf vom zweiten Client gesetzt.

Warum passiert das? Ich bin davon überzeugt, dass die Codeausführung beim Auslösen der Exception beendet sein sollte und daher der Aufruf ofy(). Save() niemals aufgerufen werden sollte.

Das Problem tritt sowohl beim lokalen App Engine-Entwicklungsserver als auch bei der Bereitstellung der Back-End-Anwendung auf den Google-Servern auf.

Edit: Das Problem scheint zu sein, dass objectify das in updateUsername erstellte UserRecord in der Datenbank speichert, obwohl ofy(). Save() nie aufgerufen wird. Warum das?

Antwort

0

Sie können mehrere andere Probleme haben, aber die Wurzel Problem ist, dass:

  1. Sie benötigen eine Transaktion
  2. Sie verwenden keine regelmäßigen Abfragen verwenden innerhalb von Transaktionen

Wenn Sie die Eindeutigkeit von Benutzernamen erzwingen möchten, müssen Sie eine separate Benutzername-Entität erstellen, deren ID der Benutzername selbst ist, und den Benutzernamen zusammen mit dem Benutzerdatensatz laden/erstellen. Da die Belastung des Benutzernamens mit dem Primärschlüssel erfolgt, können Sie die Eindeutigkeit des Benutzernamens transaktionsbedingt garantieren.

Verwandte Themen