2012-06-19 2 views
1

Je le scénario (gestion des exceptions supprimée, le code simplifié) suivant:Minimisation du verrouillage de la table sur une boucle SqlDataReader?

SqlDataReader rdr = executeQuery(query); 
while (rdr.Read()) { 
    //There are thousands of records, so this happens thousands of times 
    handleRecord(rdr); //Takes a couple of seconds 
} 
rdr.Close(); 

Ainsi, la table (en cours d'exécution sur un surpeuplé Sql Server 2000) la requête implique a partagé les verrous pendant deux heures ou plus, en fonction de la quantité d'enregistrements. Ces verrous affectent parfois d'autres applications qui interrogent cette base de données. Il m'a donc été demandé de retirer les verrous dès que possible.

Ainsi, peu de l'évidence

List<Record> rList = new List<Record>(); 
SqlDataReader rdr = executeQuery(query); 
while (rdr.Read()) { 
    //There are thousands of records, so this happens thousands of times 
    storeRecord(rList,rdr); //Takes milliseconds 
} 
rdr.Close(); 
foreach (Record r in rList) { 
    handleRecord(r); 
} 

qui mettrait une limite sur la quantité de disques que je peux gérer sur la mémoire de la machine, est-il une autre alternative?

(Cette application, je me déplace lentement à Dapper.NET, il est donc déjà une dépendance pour d'autres parties du code, dans le cas où il y a quelque chose dans Dapper qui pourrait aider à ce scénario.)

+0

Et si la requête est exécutée avec une requête de serveur SQL, l'indication no-lock? –

+0

Je veux les données aussi à jour que possible, je comprends que l'utilisation de l'indice pourrait changer cela dans certaines circonstances. –

+0

Mais l'approche rList va également avoir des données obsolètes. – Paparazzi

Répondre

0

essayera mon commenter comme une réponse pas de commentaires récents.

Sélectionnez dans une table #temp. Et une revue générale de vos serrures. Peut-être des verrous de rangée. Assurez-vous de mettre à jour les tables dans le même ordre. Qu'est-ce que handleRecord ressemble à

1

Il est un vieux sujet, mais voici une astuce que j'utilise parfois:

  1. Commandez votre requête SQL sur clé primaire.
  2. Lire les enregistrements de haut ##.
  3. Lit/tampon ces enregistrements ##.
  4. Utilisez votre tampon pour effectuer le traitement.
  5. Rappelez-vous l'ID le plus élevé.

Retour à 2 avec une modification: Vous avez lu les ## enregistrements supérieurs ID WHERE> ID le plus élevé.

De cette manière, vous pouvez lire et traiter des lots de données.

Questions connexes