2013-06-09 6 views
5

Ich kenne den Unterschied zwischen Data Reader und Data Set.Ist Data Reader besser oder Datensatz für Anwendung, bei der wir Concurrency-Problem haben können

Der DataReader ist eine bessere Wahl für Anwendungen, die einen optimierten Nur-Lese-, schnellen und nur Vorwärts-Datenzugriff erfordern.

Der Datensatz ist besser für die Anwendung, in der Sie alle Daten erhalten und aktualisieren Sie sie auf Anwendungsebene entsprechend Ihren Anforderungen und senden Sie die Änderung an die Datenbank.

Bitte löschen Sie, wenn etwas falsch in meinem Verständnis ist.

Jetzt hatte ich ein Interview dort fragte mich eine Person. Ist der Datenreader oder die Connected-Architektur für Anwendungen wie Ticketing-Systeme geeignet? Im Grunde genommen meinte sie, dass viele Benutzer versuchen würden, die gleiche Tabelle zu aktualisieren. So kommt das Concurrency-Konzept.

Wir können Disconnected Architektur verwenden, um auf Gleichzeitigkeit zu prüfen, und nur ein Benutzer kann die Tabelle zu einem Zeitpunkt aktualisieren. Aber wissen Sie nicht, wie es in Bezug auf die verbundene Architektur passiert. Würde die Verbindung zur Datenbank und insbesondere zur betreffenden Tabelle dazu führen, dass nur ein Benutzer das Update durchführt, werden andere, die später versuchen, dies nicht zu tun.

Wird die Leistung nicht beeinträchtigt, wenn alle Benutzer eine Verbindung geöffnet haben, da die Datenbank den Flaschenhals erreicht.

Ich hoffe, ich werde die Antwort bekommen, sie zu verstehen.

Antwort

4

Ich denke es ist nicht eine Frage, welche besser ist, da Daten bereits alt/ungültig ist, sobald es den Client erreicht. Das Anzeigen einer Reserviertabelle kann nützlich sein, um einen groben Überblick über die vorgenommenen Reservierungen zu erhalten, aber in der nächsten Sekunde könnte es ganz anders aussehen. Sie möchten die Rennbedingungen beseitigen. Eine gute Architektur ist notwendig, um damit zu beginnen.

Eine Möglichkeit, dies zu tun ist, das Ticket [1] zu 'reservieren'. Die Anwendung fragt nach einem Ticket, das bei den übereinstimmenden Kriterien verfügbar ist. An dieser Stelle ist bekannt, ob das Ticket verfügbar ist oder nicht. Wenn es verfügbar war, war es bereits reserviert. Dies vermeidet Mehrfachreservierungen für ein Ticket. Die nächste Reservierung (gleiche Operation/Aktion) führt dazu, dass ein anderes Ticket reserviert wird. Sie können diesem Ticket später jederzeit Informationen hinzufügen (z. B. den Besitzer des Tickets und seine Informationen). Tickets, denen keine Informationen beigefügt sind, werden nach einer bestimmten Anzahl von Minuten ablaufen und in den Pool zurückkehren. Diese Tickets können wieder 'reserviert' werden [1].

[1] Um Mehrfachzuweisungen zu vermeiden, verwenden Sie optimistic locking. Um die Frage zu beantworten, würde ich DataReader sagen. Es hält die Datenbankkommunikation auf ein Minimum (Laden und Sperren), so dass Updates so schnell wie möglich verarbeitet werden können. Denken Sie nur daran, dass Sie Probleme mit Nebenläufigkeit nicht lösen können. Es ist die Gesamtlösung, die zählt.

Beispiel

Ich weiß nicht die Anforderungen, aber da es ein Interview Frage ist werde ich ein Beispiel geben. Nimm das nicht als goldene Regel, aber von der Spitze meines Kopfes würde es in etwa so sein:

(falls erforderlich) Zuerst wird dem Benutzer ein Bildschirm angezeigt, dass noch Tickets im System übrig sind reserviert. Öffnen Sie eine Verbindung und einen Leser, um die Anzahl der verfügbaren Tickets für die Reservierung zu lesen. Schließen Sie den Reader und die Verbindung. Der Benutzer fährt mit dem nächsten Bildschirm fort.

SELECT COUNT(*) 
FROM [Tickets] 
WHERE ([LastReserved] IS NULL OR [LastReserved] <= DATEADD(MINUTE, GETDATE(), @ticketTimeout)) 
    AND [TickedAssignedToUserId] IS NULL; 

Der Benutzer fordert eine x-Menge von Tickets und fährt mit dem nächsten Bildschirm. In diesem Moment prüft das System mit optimistischer Sperrung, ob genügend Tickets verfügbar sind. Einfach eine Verbindung öffnen und die folgende Abfrage ausführen (mit der Transaktion!):

UPDATE TOP(@numberOfTicketsRequested) [Tickets] 
SET [LastReserved]=GETDATE() 
WHERE ([LastReserved] IS NULL OR [LastReserved] <= DATEADD(MINUTE, GETDATE(), @ticketTimeout)) 
    AND [TickedAssignedToUserId] IS NULL; 

Die Anzahl der Zeilen sollten gleich @numberOfTicketsRequested betroffen sein. Wenn dies der Fall ist, übergeben Sie die Transaktion und erhalten Sie die Ticket-ID. Andernfalls rollback und sag dem Benutzer, dass keine Tickets mehr verfügbar sind. An dieser Stelle benötigen wir die Datensatzinformationen, also möchten Sie vielleicht auch die Kennung erhalten.

An diesem Punkt erhält der Benutzer @ticketTimeout Minuten Zeit, um ihre Benutzerdetails einzugeben. Wenn es richtig gemacht, kann die folgende Abfrage ausgeführt werden:

UPDATE TOP(@numberOfTicketsRequested) [Tickets] 
SET [TickedAssignedToUserId][email protected] 
WHERE [TicketId][email protected] AND [LastReserved][email protected] AND [TickedAssignedToUserId] IS NULL; 

Wenn der Benutzer hat länger gedauert als, sagen wir 10 Minuten und jemand anderes mit dem gleichen Ticket erneut angefordert, dann wird der LastReserved Zeitstempel geändert hat. Wenn der erste Benutzer versucht hat, das Ticket mit seinen Details zu reservieren, stimmt das Update nicht mehr mit dem ursprünglichen LastReserved Zeitstempel überein, und das Update zeigt nicht genügend betroffene Zeilen (= Rollback) an. Wenn es mit der Anzahl der betroffenen Zeilen übereinstimmt, hat der Benutzer die Tickets erfolgreich reserviert (= Festschreibung).

Beachten Sie, dass keine Ticketinformationen mit Ausnahme der Ticketbezeichner die Anwendung erreicht haben. Ich habe auch keine Benutzerregistrierung aufgenommen. Es werden keine vollständigen Tabellen übergeben, und Sperren werden nur minimal verwendet (nur für zwei kurze Aktualisierungen).

+0

Danke für den Link zum optimistischen Sperren. Concurrency wäre damit definitiv gelöst. Wenn viele Benutzer versuchen, die verfügbaren Tickets abzurufen und dann versuchen, das Ticket zu buchen. Da bei DataReader die Verbindung immer geöffnet bleibt. Dies beeinträchtigt nicht die Belastung des Datenbankservers. Wenn ich Disconnected Architecture verwende, kann Locking angewendet werden und das Laden auf dem Datenbankserver wäre auch weniger. Ja, Speicherprobleme wären vorhanden, aber es wird mehr auf das Leistungsproblem, den Datenbankserver oder das Speicherproblem kommen. – user2432715

+0

Als Nebenbemerkung: 'DataReader' implementiert' IDisposable', sodass Ressourcen (Verbindung) an den Verbindungspool zurückgegeben werden. Zu diesem Zeitpunkt können aufgrund der Verbindung, die verfügbar geworden ist, andere Lese-/Schreibvorgänge verwendet werden, wodurch der Durchsatz verbessert wird. Beachten Sie, dass es sich bei der genannten Sperre nicht um eine herkömmliche Sperre handelt (sie wird erst gesperrt, wenn Sie sie wieder freigeben). – Caramiriel

+0

So sind die folgenden Schritte, um den DataReader effizient zu nutzen: 1. Öffnen Sie die Verbindung 2. Zeigen Sie die Daten dem Benutzer mit DataReader. 3. Schließen Sie die Verbindung. (Hier wird die Ressource frei sein) Jetzt kommt die Aktualisierung. Der Benutzer wird nun einen Datensatz aktualisieren. 4. Ooen Connection erneut 5. Verwenden Sie den Daten-Reader, um den jeweiligen Datensatz zu aktualisieren. 5. Schließen Sie es. Verriegelung entsprechend angewendet – user2432715

Verwandte Themen