2016-06-28 3 views
0

Ich habe eine Seite machen 2 Ajax-Aufrufe zu einer Web Api Methode, die die folgenden Logik funktioniert:Web Api Concurrency Probleme prüfen, ob Artikel Exists

  1. Prüfen, ob das Element vorhanden ist. Wenn ja, rufen Sie den Artikel ab.
  2. Wenn das Element nicht existiert, erstellen Sie es.

Code:

if (!_db.Items.Any(x => x.EntityId == requestItem.EntityId &&        
          x.UserId == request.UserId)) 
{ 
    // item does not exist, so create it. 
    var item = new Item(); 
    // set some properties here... 

    _db.Items.Add(item); 
} 

Das Problem, das ich habe, ist, dass Einzelteile sehr schnell erstellt werden, und da die Ajax-Aufrufe gleichzeitig laufen, ich mit zwei Elementen enden. Aber ich möchte nur zulassen, dass 1 erstellt wird. Ich möchte dem Benutzer keinen Fehler zurückgeben. Ich möchte in der Lage sein, nur einen Artikel zu erstellen, wenn ein wirklich nicht existiert. Wie kann ich das erreichen?

Ich sah diese post auf die Einstellung von Parallelitätsprüfungen mit Entity Framework, aber ich möchte nicht einen Fehler zurück an den Benutzer zu werfen, so dass ich nicht sicher bin, wenn EF Parallelität ist, was ich tun muss. Werte überschreiben sich nicht gegenseitig. Zu der (fast) gleichen Zeit finden zwei Anrufe statt, so dass beide sehen, dass es 0 Einträge in der Tabelle gibt.

+0

Wenn Sie keinen Fehler zurück zum Benutzer wollen, wickeln Sie den Prozess einfach mit einem try-catch. – Tommy

+0

Ich gehe nicht in Daten über, die einen vorhergehenden Wert überschreiben. Das Überprüfen einer RowVersion-Eigenschaft funktioniert nicht, da das Element noch nicht existiert. Ich habe Probleme, 1 zu erstellenden Artikel zu beschränken. – duyn9uyen

+0

Wird ein kombinierter eindeutiger Schlüssel akzeptiert? – Tommy

Antwort

0

Sie müssen eine eindeutige ID in Ihrer Anfrage festlegen, um doppelte Buchung auf dem Server zu bestimmen.

Was ich vorschlagen würde ist, dass beim Laden der Seite eine UID generieren. Wenn der Benutzer auf die Schaltfläche klickt, die die Anforderung an die Web-API sendet, übergeben Sie die generierte UID.

Wenn der Benutzer nun mehrmals auf die Schaltfläche klickt, wird derselbe Wert für die UID übergeben, da er beim Laden der Seite und nicht beim Klicken des Benutzers generiert wird.

Auf dem Server, machen Sie die gleiche Prüfung.

if (!_db.Items.Any(x => x.EntityId == requestItem.EntityId &&        
          x.UserId == request.UserId)) 
{ 
    // item does not exist, so create it. 
    var item = new Item(); 
    // set some properties here... 

    _db.Items.Add(item); 
} 

Ich würde vorschlagen, die UID aus der Anforderung als einen Try-Catch-Block hinzufügen requestItem.EntityId

Keine Notwendigkeit verwenden, da Sie eine einfache if-Anweisung verwenden, die ausreichend ist. Sie finden einen Javascript UUID generierenden Code oder eine Bibliothek :)

+0

Danke, aber ich brauche nicht eine Doppelpost zu verhindern. Ich möchte in der Lage sein, damit umzugehen, wenn Kunden parallele Ajax-Versprechen machen. – duyn9uyen