ASP.NET, EF4 und Threads: Klappt das eigentlich?

Seit einiger Zeit arbeitete ich mich in die Welt der Programmierung von Web-Applikationen ein, mit Hilfe von ASP.NET MVC2, unter Verwendung von Entity Framework 4 (EF4) für den Datenbank-Zugriff.

Es ging eine ganze Weile, bis mir auffiel, dass in allem Demo-Code und in allen Demo-Projekten wie etwa dem Nerd Dinner nirgends die Rede war von Datenkonsistenz-Problemen, die es geben kann bei Verwendung von ASP.NET und EF4. ASP.NET arbeitet per se mit Multi-Threading, und deshalb können die Datenbankzugriffe ganz schön durcheinandergehen, wenn man auf einem Web-Server eine anständige Menge an Zugriffen hat. Zudem bringt die Verwendung von EF4 mit sich, dass in einem ObjectContext-Objekt eine Menge Daten zwischengespeichert werden können. Die Gefahr, dass sich mehrere Nutzer meiner Web-Applikation gegenseitig ihre Änderungen überschreiben, schien mir real zu sein.

Heute bin ich deshalb dieser Frage auf den Grund gegangen und dabei auf eine kleine Überraschung gestossen.

Multi-Threading in ASP.NET findet statt auf der Ebene der Requests: 1 Request wird jeweils in einem eigenen Thread ausgeführt. In ASP.NET MVC2 werden Controllers pro Request jeweils neu erzeugt; wenn man also wie in den Samples vorgegeben einen EF4-Objekt-Kontext als normale Property der Controller-Klasse implementiert, leben diese Objekte nur recht kurz, womit sich auch das Risiko von Konflikten deutlich reduziert.

Nebenbei bemerkt: Solange man nicht selbst Threads erzeugt in seiner MVC-Applikation, sondern nur dem „automatischen“ Threading von ASP.NET unterworfen ist, hat man also kein Problem damit, dass ObjectContext wie viele andere Framework-Klassen nicht thread-safe ist. Man darf nur nicht auf die Idee kommen, ein solches Objekt static zu deklarieren in seinem Controller!

Soweit, so gut, aber das Risiko von Konflikten sinkt damit natürlich nicht auf Null.

Die erwähnte Überraschung (zumindest für mich) fand sich schliesslich in diesem MSDN-Artikel: Per Default prüft EF4 bei Datenveränderungen nicht auf irgendwelche Optimismus-Verletzungen, sondern überschreibt einfach munter mit den aktuellen Daten in den Entities.

Mir persönlich scheint das ein etwas fragwürdiger Default zu sein, aber zum Glück kann man ihn relativ einfach überstimmen: Auf der Ebene einzelner Properties in einem EF4-Datenmodell ändert man einfach die Eigenschaft Concurrency Mode weg vom Default None auf Fixed. Die korrekte Behandlung einer OptimisticConcurrencyException, die es dann bei SaveChanges() geben kann, wird z.B. in diesem MSDN-Artikel erläutert. Wieso allerdings dieser Modus „fixed“ heisst, hat sich mir bisher nicht erschlossen…

Wenn’s etwas komplizierter wird und man z.B. einen eigenen Datenzugriffs-Layer in seiner Applikation implentieren will, findet man hier gute Erläuterungen zu Varianten, wie man die „Lebenszeit“ von ObjectContext-Objekten organisieren kann.

Veröffentlicht in Allgemein. Schlagwörter: , , . 1 Comment »

Eine Antwort to “ASP.NET, EF4 und Threads: Klappt das eigentlich?”

  1. Sebastian Says:

    Hallo René, ich denke das dieses „Default“ Concurrency-Verhalten durchaus so gewollt und sinnvoll ist, da dort zus. Prüfungen stattfinden (die Performance kosten) ob die Daten noch aktuell sind. Auch ist es für einen Automatismus nicht von Natur aus klar erkennbar was das Concurrency Argument (z.B. Timestamp oder Versionsnummer) ist. Eine automatische „Versionssicherheit“ ist somit gar nicht möglich. Aber wie du schon schreibst ist es recht einfach die Concurrency zu konfigurieren und EF4 mitzuteilen auf was geachtet werden soll.

    Gruß Sebastian


Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: