Question

Considérant une table de forum et de nombreux utilisateurs simultanément des messages dans l'insertion, comment la sécurité est cette transaction?

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

 DECLARE @LastMessageId SMALLINT
 SELECT @LastMessageId = MAX(MessageId)
 FROM Discussions
 WHERE ForumId = @ForumId AND DiscussionId = @DiscussionId

 INSERT INTO Discussions
 (ForumId, DiscussionId, MessageId, ParentId, MessageSubject, MessageBody)
 VALUES
 (@ForumId, @DiscussionId, @LastMessageId + 1, @ParentId, @MessageSubject, @MessageBody)

IF @@ERROR = 0
BEGIN
 COMMIT TRANSACTION
 RETURN 0
END

ROLLBACK TRANSACTION
RETURN 1

Ici je lis la dernière MessageId et incrémenter. Je ne peux pas utiliser le champ Identity car il doit être incrémentée pour chaque message inséré dans un groupe (pas tous d'insertion de messages dans la table.)

Était-ce utile?

La solution

Votre transaction devrait être tout à fait sûr en effet - consultez les MSDN docs sur le SERIALIZABLE niveau de transaction :

SERIALIZABLE

  

Indique les éléments suivants:

     
      
  • Déclarations ne peuvent pas lire les données qui ont été modifiés mais pas encore   par d'autres transactions.

  •   
  • Aucune autre transaction ne peut modifier les données qui a été lu par le   transaction en cours jusqu'à ce que le courant   finalise la transaction.

  •   
  • D'autres transactions ne peut pas insérer de nouvelles lignes avec des valeurs clés   entreraient dans la gamme de clés lecture   par des déclarations contenues dans le courant   transaction jusqu'à ce que le courant   finalise la transaction.

  •   
     

serrures Range sont placés dans la gamme des valeurs clés qui correspondent à la   conditions de recherche de chaque déclaration   exécutée dans une transaction. cela bloque   d'autres opérations de mise à jour ou   l'insertion des lignes qui serait admissible   pour l'une des déclarations exécutées par   la transaction en cours. Ça signifie   que si l'une des déclarations dans un   transaction sont exécutées une seconde   temps, ils liront le même ensemble de   Lignes. Les verrous de gamme sont maintenus jusqu'à   la transaction terminée. C'est le   la plus restrictive de l'isolement   les niveaux car il verrouille les gammes entières   des clés et maintient les verrous jusqu'à ce que   finalise de transaction. Car   est inférieure concurrency, utilisez cette option   seulement si nécessaire. Cette option a   le même effet que la mise en HOLDLOCK sur   toutes les tables de toutes les instructions SELECT dans   une transaction.

Le principal problème avec ce niveau d'isolation des transactions est que c'est une jolie charge lourde sur le serveur, et sérialisés (comme son nom l'indique) tout accès, donc les performances de votre serveur et l'évolutivité souffriront, par exemple avec un très grand nombre d'utilisateurs, vous éventuellement obtenir beaucoup de délais d'attente pour les utilisateurs en attente d'une transaction à la fin.

Donc, en utilisant l'approche plus légère d'un identifiant de message global que INT IDENTITY est certainement beaucoup mieux!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top