2010-02-24 3 views
3

J'ai une table simple dans mon SQL Server 2008 DB:Modifier SQL résultats avant le retour de la procédure stockée

Tasks_Table 
-id 
-task_complete 
-task_active 
-column_1 
-.. 
-column_N 

Les instructions stocke les tables pour les tâches inachevées qui doivent être exécutées par un service.

Je veux être en mesure de faire évoluer mon système à l'avenir. Jusqu'à présent, seulement 1 service sur 1 ordinateur lu de la table. J'ai une procédure stockée, qui sélectionne toutes les tâches inachevées et inactives. Lorsque le service commence à traiter les tâches, il met à jour l'indicateur task_active dans toutes les lignes renvoyées.

Pour activer la mise à l'échelle du système, je souhaite activer le déploiement du service sur plusieurs machines. Étant donné que je veux empêcher une tâche d'être renvoyée à plus d'un service, je dois mettre à jour la procédure stockée qui renvoie des tâches inachevées et inactives. J'ai pensé que je devais verrouiller la table (seulement 1 lecteur à la fois - je sais que je dois utiliser un ISOLATION LEVEL approprié), et met à jour le drapeau task_active dans chaque rangée du jeu de résultats avant de retourner le jeu de résultats . Donc, ma question est de savoir comment modifier le jeu de résultats SELECT dans la procédure stockée avant de le renvoyer?

Répondre

2

C'est le modèle de dequeue typique, est mis en oeuvre en utilisant la clause de sortie et et est décrit dans le MSDN, reportez-vous au paragraphe Queues dans OUTPUT Clause (Transact-SQL):

UPDATE TOP(1) Tasks_Table WITH (ROWLOCK, READPAST) 
SET task_active = 1 
OUTPUT INSERTED.id,INSERTED.column_1, ...,INSERTED.column_N 
WHERE task_active = 0; 

Le ROWLOCK, indice READPAST permet un débit élevé et élevé concurence: les threads multiples/traités peuvent mettre en file d'attente de nouvelles tâches en même temps que des threads multiples/des tâches de mise en file d'attente de processus. Il n'y a pas de garantie de commande.

Mise à jour

Si vous souhaitez commander le résultat que vous pouvez utiliser un CTE:

WITH cte AS (
    SELECT TOP(1) id, task_active, column_1, ..., column_N 
    FROM Task_Table WITH (ROWLOCK, READPAST) 
    WHERE task_active = 0 
    ORDER BY <order by criteria>) 
UPDATE cte 
    SET task_active = 1 
OUTPUT INSERTED.id, INSERTED.column_1, ..., INSERTED.column_N; 

Je en ai parlé et d'autres techniques de mise en file/dequeue sur l'article Using Tables as Queues.

+0

Existe-t-il un moyen de commander le Task_Table avant d'appeler TOP (1) sans perdre le ROWLOCK et READPAST? – m0sa

Questions connexes