2009-03-06 11 views
1

J'ai 2 programmes par lots, 1 est un programme qui envoie un courrier électronique et un autre envoie un fax. Ils accèdent tous les deux à une table nommée QUEUE.Verrouillage dans SQL Server

Dans le programme expéditeur d'email, voici ce qui se passe en relation avec QUEUE. Pour chaque enregistrement QUEUE qui satisfait les critères:

  1. Locks fiche 1 dans QUEUE tableau:
    select 1 from QUEUE with (UPDLOCK) where id = 1
  2. processus d'envoi de courrier électronique
  3. Supprimer fiche 1 dans le tableau QUEUE:
    delete from QUEUE where id = 1
  4. commettras transaction (la transaction n'est pas une validation automatique)

Dans le programme expéditeur de télécopie, des étapes similaires se produisent également, sauf qu'à l'étape 2, nous envoyons des télécopies (bien sûr).

Le problème est que parfois la suppression de QUEUE rejette une exception qu'elle est verrouillée. De ce fait, la réexpédition des emails/fax arrive. Je suis sûr que le groupe d'enregistrements traités par ces programmes ne se croisent pas.

Il semble que delete tente d'obtenir un verrou de mise à jour (U) sur d'autres enregistrements de la table, bien qu'un seul enregistrement doive être supprimé. Une exception se produit donc lorsque d'autres transactions ont des verrous sur d'autres enregistrements de la même table. Avec cela, j'ai besoin de savoir s'il y a une option pour faire "supprimer" opération ne pas acquérir des verrous sur les enregistrements autres que pour l'enregistrement, il va supprimer. Parce qu'il semble que le problème est avec l'opération "delete" prenant des verrous sur d'autres enregistrements dans la table.

D'ailleurs, voici quelques informations sur la base de données (je ne sais pas s'ils vous aideront):

  • Lire Snapshot Engagé est activé
  • Etat Isolation photo est affichée sur

Répondre

2

Avez-vous essayé d'utiliser l'indicateur WITH ROWLOCK ou WITH NOLOCK dans l'instruction delete?

Avez-vous lu this article? Il vous suggère d'utiliser (UPDLOCK, READPAST) pour éviter le problème rencontré

+0

voulez-vous dire sur l'instruction delete ou select (je n'ai aucune instruction de mise à jour dans mon pseudo-code)? – rizza

+0

Je pense qu'en utilisant XLOCK dans select et XLOCK, READPAST sur la suppression pourrait fonctionner (testé, la suppression n'est pas bloquée par le verrouillage sur d'autres tables et l'instruction select verrouille l'enregistrement par rapport à une autre instruction essayant de verrouiller l'enregistrement. beaucoup pour votre suggestion. – rizza

0

Parfois, une serrure se détache du verrouillage d'une seule rangée pour verrouiller une section d'une table ou verrouiller une table entière. C'est très probablement pourquoi vous obtenez des verrous sur les enregistrements que vous n'utilisez pas réellement dans la transaction. Au lieu d'utiliser une transaction pour verrouiller les enregistrements, vous pouvez utiliser un champ d'état pour marquer les enregistrements qui sont traités.

Exemple:

verrouillage des enregistrements, puis obtenir le dossier qui a été verrouillé avec succès:

update queue set status = 'email_processing' where status is null and id = 1 
select email, message from queue where status = 'email_processing' 

Lorsque vous n'utilisez pas explicitement une transaction chaque requête est exécutée dans sa propre transaction, de sorte que la requête de mise à jour peut changer en toute sécurité le statut car il vérifie l'état actuel dans la même requête.

Lorsque vous avez terminé l'envoi, supprimer les enregistrements:

delete from queue where status = 'email_processing' 

L'expéditeur du fax serait bien sûr utiliser un statut différent (comme « fax_processing ») afin que les enregistrements marqués sont isolés.

+0

Avec la suggestion, ce qui m'inquiète, c'est si je rencontre une erreur de verrouillage pendant la durée de la suppression. Même si j'enlève les verrous, je suis toujours enclin à rencontrer une erreur de verrouillage lors de la suppression (il verrouille d'autres enregistrements). Ce que je pense est sur cette partie est que le code essaie de supprimer jusqu'à ce qu'il réussisse. – rizza

+0

Oui, vous pourriez le faire. Cependant, sans transaction, vous n'êtes pas susceptible de rencontrer des verrous. La base de données attendra normalement qu'une mise à jour/suppression soit terminée avant d'exécuter la suivante. C'est surtout quand vous avez un long processus dans une transaction ou une situation de blocage que c'est un problème. – Guffa

+0

En fait, ce que nous expérimentons est la période de verrouillage du délai dépassé et l'impasse. Ce sont les deux erreurs que j'ai trouvées dans notre journal des erreurs. Merci pour la suggestion mais je pense que la suggestion de Nick pourrait fonctionner (bien que j'utilise XLOCK au lieu de UPDLOCK). – rizza