Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
EFCore Verbindungsprobleme und doppelte Einträge
schuppsl
myCSharp.de - Member



Dabei seit:
Beiträge: 786

Themenstarter:

EFCore Verbindungsprobleme und doppelte Einträge

beantworten | zitieren | melden

verwendetes Datenbanksystem: MSSQL

Hallo zusammen.

Eine Webanwendung speichert Formulardaten in einer Datenbank.
Es gibt also einen Senden-Button, welcher eine Backend-Methode zur Speicherung ausführt.

Per EFCore werden die Daten dann gespeichert.
Es scheint nun so, dass unser Datenbankserver ab und zu Probleme damit hat, Verbindungen aufzubauen.

Das daraus resultierende eigentliche Problem gestaltet sich aber folgendermaßen:

Absendebutton wird gedrückt, es wird versucht, die DB - Verbindung herzustellen, was aber in seltenen Fällen 5-8 Sekunden dauern kann.
Der User der Webanwendung wartet kurz und drückt dann nochmals auf Absenden, da es anscheinend beim ersten Mal nicht funktioniert hat.
Somit wird die "hängende" Methode erneut aufgerufen und EFCore versucht nochmals die Verbindung aufzubauen.

Irgendwie, irgendwo laufen also 2 Threads und beide "hängen" beim Verbindungsaufbau. (Using)
Geht es dann, so werden die Formulardaten doppelt in der DB gespeichert, da die Funktion zweimal aufgerufen wurde.

Der Verbindungsaufbau wird per Using gemacht:


using (con= new MyContext())
{
//
}

Und irgendwo hier hängt es dann.
Aus meiner Sicht ist das Problem, dass die Verbindung 2x aufgebaut und die Tabelle 2x in 2 verschiedene DbContext gelesen wird.
Deshalb schlagen Prüfungen, ob der Eintrag schon vorhanden ist (spezielle Kombination aus Key+ weitere Felder) fehl.

Es ist also ein Grundsatzproblem, was ich nicht verstanden habe.

Entprellung des Sendenbuttons und Hinweise in der Webanwendung- Ja.
Prüfung, ob der Eintrag schon in der DB existiert - Ja ( nützt hier aber nichts)
Klärung, warum die DB ab und zu die Verbindung so langsam aufbaut - Ja.

Damit kann man das Problem entschärfen oder umgehen, aber gelöst ist es grundsätzlich nicht.

Parallelitäts Erkennung nützt hier mMn nach auch nicht viel, da in die Tabelle nur geschrieben wird und derselbe Datensatz nicht von mehreren verändert wird.

Was ist hier also das Problem am Design, was habe ich nicht verstanden und wie hieße das "Zauberwort" für so einen Fall?

Ganz herzlichen Dank im Voraus.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16234

beantworten | zitieren | melden

Zitat von schuppsl
Irgendwie, irgendwo laufen also 2 Threads und beide "hängen" beim Verbindungsaufbau.
Ja, so funktionieren .NET Webanwendungen. Jeder Request ist (grundlegend) ein Thread.

Zitat von schuppsl
Funktion zweimal aufgerufen wurde.
Methode.
Zitat von schuppsl
Der Verbindungsaufbau wird per Using gemacht:
Was generell ein Anti-Pattern darstellt und den Code untestbar macht.
Mit dem Problem hat das nichts zutun.
Zitat von schuppsl
Aus meiner Sicht ist das Problem, dass die Verbindung 2x aufgebaut und die Tabelle 2x in 2 verschiedene DbContext gelesen wird.
Es ist gut, dass hier zwei Contexte verwendet werden, weil der Context nicht Thread-Safe ist und daher pro Request ein Context erstellt werden muss.
Zitat von schuppsl
Deshalb schlagen Prüfungen, ob der Eintrag schon vorhanden ist
Naja, Du prüfst offenbar halt nur Client-seitig.

Zitat von schuppsl
Prüfung, ob der Eintrag schon in der DB existiert - Ja ( nützt hier aber nichts)
Doch, der würde was bringen, wenn es in der Datenbank erfolgt.
Du prüfst aber eben innerhalb einer potentiellen Race Condition: natürlich ist das dann nicht stabil.
Zitat von schuppsl
Damit kann man das Problem entschärfen oder umgehen, aber gelöst ist es grundsätzlich nicht.
Das is generell kein Problem mit EF, sondern das ist ein Problem mit jeder Datenbank-Interaktion in jeder Umgebung.
SQL INSERT but avoid duplicates

Bei Dir tritt es eben häufiger auf, weil der User durch eine schlechte Performance der Anwendung bewusst das Formular erneut absendet und daher erst die Situation aufkommt, dass die Aktion zwei mal erfolgt.
Ansonsten würde das - auch wenn das grundlegende Potential weiter bestehen würde - kaum auftreten.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
schuppsl
myCSharp.de - Member



Dabei seit:
Beiträge: 786

Themenstarter:

beantworten | zitieren | melden

Ganz lieben Dank.
Zitat
Naja, Du prüfst offenbar halt nur Client-seitig.

Doch, der würde was bringen, wenn es in der Datenbank erfolgt.
Du prüfst aber eben innerhalb einer potentiellen Race Condition: natürlich ist das dann nicht stabil.

Die Prüfung auf vorhandenen Eintrag wird innerhalb der Using-Anweisung gemacht.
Zitat
Doch, der würde was bringen, wenn es in der Datenbank erfolgt.
Du prüfst aber eben innerhalb einer potentiellen Race Condition: natürlich ist das dann nicht stabil.
So ist es.

Prüfung in der Datenbank? Interessant.

Also ist die Entprellung des Absendebuttons der beste Weg um das Problem zu minimieren.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16234

beantworten | zitieren | melden

Zitat von schuppsl
Also ist die Entprellung des Absendebuttons der beste Weg um das Problem zu minimieren.

Als "beste" würde ich das sicherlich nicht bezeichnen, aber wäre vermutlich ein Workaround. "Beste" wäre es dort zu verhindern, wo es auftritt: und das ist die Datenbank.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
schuppsl
myCSharp.de - Member



Dabei seit:
Beiträge: 786

Themenstarter:

beantworten | zitieren | melden

Und wie könnte diese Lösung ungefähr aussehen?
Stored Procedure, die das vorab prüft?
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von schuppsl am .
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 16234

beantworten | zitieren | melden

Hab Dir den Link SQL INSERT but avoid duplicates nicht umsonst gegeben.
Da stehts drin und ist selbst nach 11 Jahren immer noch eine adäquate Lösung.
- performance is a feature -

Microsoft MVP - @Website - @blog - @AzureStuttgart - github.com/BenjaminAbt
private Nachricht | Beiträge des Benutzers
schuppsl
myCSharp.de - Member



Dabei seit:
Beiträge: 786

Themenstarter:

beantworten | zitieren | melden

Ganz herzlichen Dank!
private Nachricht | Beiträge des Benutzers