Data Reader est-il meilleur ou Data Set pour les applications où nous pourrions avoir un problème de concurrency?

Je connais la différence entre Data Reader et Data Set.

Le DataReader est un meilleur choix pour les applications qui nécessitent un access aux données optimisé en lecture seule, rapide et uniquement en avant.

L'set de données est mieux pour l'application où vous pouvez get toutes datatables et les mettre à jour selon vos besoins au niveau de l'application et soumettre la modification à la database.

S'il vous plaît, clarifiez s'il y a quelque chose qui ne va pas dans ma compréhension.

Maintenant, j'ai eu une interview, une personne m'a demandé. Le datareader ou l'architecture connectée est-elle bonne pour une application comme un système de ticketing. Fondamentalement, elle voulait dire que de nombreux users pourraient essayer de mettre à jour la même table. Ainsi, le concept de Concurrency vient.

Nous pouvons utiliser l'architecture déconnectée pour vérifier la simultanéité et laisser un seul user mettre à jour la table à la fois. Mais ne sais pas comment cela se passe en termes d'architecture connectée. Est-ce que la connection à la database et en particulier à la table concernée ferait en sorte qu'un seul user fasse la mise à jour alors que d'autres qui essaieront de le faire plus tard ne pourront pas le faire.

N'affectera pas la performance si tous les users ont ouvert une connection car la database atteindra le goulot d'étranglement.

J'espère que j'aurai la réponse pour les comprendre.

Je pense que ce n'est pas un problème, car datatables sont déjà anciennes / invalides une fois qu'elles ont atteint le client. Montrer une table de réservations peut être utile pour avoir une idée approximative des réservations faites, mais cela peut être totalement différent dans la seconde suivante. Vous voulez éliminer les conditions de course. Une bonne architecture est nécessaire pour commencer.

Une façon de faire est de «réserver» le ticket [1]. L'application request d'get un ticket disponible en fonction des critères correspondants. À ce stade, il est connu que le billet est disponible ou non. S'il était disponible, il était déjà réservé. Cela évite plusieurs réservations pour un ticket. La réservation suivante (même opération / action) aboutira à la réservation d'un ticket différent. Vous pouvez toujours append des informations à ce ticket plus tard (comme le propriétaire du ticket et ses informations) si nécessaire. Les tickets qui ne contiennent pas d'informations seront expirés après un certain nombre de minutes et returnneront à la piscine. Ces tickets peuvent être "réservés" à nouveau [1].

[1] Pour éviter plusieurs affectations, utilisez le locking optimiste .

Pour répondre à la question, je dirais DataReader . Il maintient la communication de la database à un minimum (charger et verrouiller), de sorte qu'il peut gérer les mises à jour aussi vite que possible. Gardez juste à l'esprit que choisir l'un sur l'autre ne résout pas les problèmes de concurrency. C'est la solution totale qui count.

Exemple

Je ne connais pas les exigences, mais puisque c'est une question d'entrevue, je vais donner un exemple. Ne prenez pas cela comme une règle d'or, mais sur le bout de ma tête ce serait quelque chose comme ceci:

(si nécessaire) Tout d'abord, l'user reçoit un écran indiquant qu'il rest des tickets dans le système pouvant être réservés. Ouvrez une connection et un lecteur pour lire le nombre de billets disponibles pour la réservation. Fermez le lecteur et la connection. L'user passe à l'écran suivant.

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

L'user request un nombre x de tickets et passe à l'écran suivant. À ce moment, le système vérifie avec un locking optimiste s'il y a suffisamment de tickets disponibles. Il suffit d'ouvrir une connection (avec transaction!) Et d'exécuter la requête suivante:

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

Le nombre de lignes affectées doit être identique à @numberOfTicketsRequested. Si c'est le cas, validez la transaction et obtenez son identifiant de ticket. Sinon, annulez et dites à l'user qu'il n'y a plus de billets disponibles. À ce stade, nous avons besoin des informations d'logging, vous pouvez donc également avoir l'identifiant.

À ce stade, l'user obtient @ticketTimeout nombre de minutes pour entrer ses informations user. Si cela est fait correctement, la requête suivante peut être exécutée:

 UPDATE TOP(@numberOfTicketsRequested) [Tickets] SET [TickedAssignedToUserId]=@userId WHERE [TicketId]=@Id AND [LastReserved]=@lastReserved AND [TickedAssignedToUserId] IS NULL; 

Si l'user a pris plus de 10 minutes et que quelqu'un d'autre a demandé à nouveau le même ticket, l'horodatage LastReserved a été modifié. Lorsque le premier user a tenté de réserver le ticket avec ses détails, la mise à jour ne correspond plus à l'horodatage LastReserved origine et la mise à jour affichera pas assez de lignes affectées (= rollback). S'il correspond au nombre de lignes affectées, l'user a réservé les tickets (= commit).

Notez qu'aucune information de ticket, à l'exception des identifiants de ticket, n'a atteint l'application. Je n'ai pas non plus inclus l'inscription de l'user. Aucune table complète n'est passée, et les verrous sont simplement utilisés au minimum (juste pour deux mises à jour courtes).