J'ai beaucoup lu sur la prévention des conditions de course, mais généralement avec un enregistrement dans un scénario plus élevé. Par exemple: Atomic UPSERT in SQL Server 2005Prévenir les conditions de course sur plusieurs rangées
J'ai une exigence différente, et il est d'empêcher les conditions de course sur plusieurs rangées. Par exemple, dire que j'ai la structure de tableau suivant:
GiftCards:
GiftCardId int primary key not null,
OriginalAmount money not null
GiftCardTransactions:
TransactionId int primary key not null,
GiftCardId int (foreign key to GiftCards.GiftCardId),
Amount money not null
Il pourrait y avoir plusieurs processus insérer dans GiftCardTransactions
et je dois éviter d'insérer si SUM(GiftCardTransactions.Amount) + insertingAmount
irait plus GiftCards.OriginalAmount
.
Je sais que je pourrais utiliser TABLOCKX
sur GiftCardTransactions
, mais évidemment ce ne serait pas faisable pour beaucoup de transactions. Une autre façon serait d'ajouter une colonne GiftCards.RemainingAmount
et ensuite j'ai seulement besoin de verrouiller une ligne (mais avec possibilité d'escalade de verrou), mais malheureusement ce n'est pas une option pour moi en ce moment (cela aurait-il été la meilleure option?) . Au lieu d'essayer d'empêcher l'insertion en premier lieu, peut-être la réponse est d'insérer simplement, puis sélectionnez SUM(GiftCardTransactions.Amount)
, et l'annulation si nécessaire. C'est un cas limite, donc je ne m'inquiète pas d'utiliser inutilement des valeurs PK, etc.
Donc la question est, sans modifier la structure de la table et en utilisant n'importe quelle combinaison de transactions, niveaux d'isolement et astuces, comment puis-je atteindre ceci avec une quantité minimale de verrouillage?