2012-04-26 2 views
0

Scénario: Une fonction de sauvegarde lit d'abord le nombre total de lignes d'une table dans la base de données. En fonction du nombre de lignes, une valeur d'entrée unique est calculée. Cette valeur est incluse dans la ligne qui est ensuite insérée dans la même table.Comment éliminer les conditions de concurrence pendant la transaction db - lire le nombre de lignes à partir de db, calculer l'entrée, puis insérer la valeur dans db?

Problème: Deux instances du même objet exécutent la fonction de sauvegarde en même temps. Ici, "en même temps" est le temps qu'il faut à l'application pour lire et insérer une ligne dans la base de données. Ainsi, par exemple,

  • l'utilisateur clique sur un sauvetage bouton >> Lectures qu'il ya 3 lignes de la table >> Calcule f (3) en tant que valeur d'entrée unique pour la nouvelle ligne >> prépare la nouvelle ligne à insérer dans la table ...

  • L'utilisateur B clique sur le bouton de sauvegarde >> (puisque l'utilisateur A n'a pas inséré la nouvelle ligne) Lit qu'il y a 3 lignes dans le tableau >> Calcule f (3) ce qui n'est PAS une valeur unique (ERREUR!) >> ...

Comment remédier à cette situation? Je ne suis pas capable de modifier la logique de transaction db car une couche ORM abstraite est malheureusement utilisée. J'ai le plein contrôle sur le code cependant. Toute suggestion sera très utile.

J'ai déjà essayé de mettre un verrou() autour de la fonction de sauvegarde, mais cela n'aide pas.

+0

Quel est le but de ce calcul unique? – mgnoonan

+0

Comment le nombre de lignes est-il récupéré? Est-ce via un appel de procédure stockée, ou via votre ORM? Peut-être que votre couche ORM met en cache le nombre de lignes de l'utilisateur A? Cela pourrait expliquer pourquoi la serrure ne fonctionne pas. – KazR

+0

@mgnoonan Le calcul unique consiste à créer un identifiant pour l'enregistrement donné. Cette spécification d'identifiant doit être séquentielle selon l'exigence. – Tom

Répondre

0

J'ai fini par tirer parti de l'ID généré par DB (auto-incrémentation) pour faire mes calculs. Étant donné que rowcount et ID n'étaient pas synchronisés, ajustez le nouvel ID personnalisé en ajoutant un entier à la nouvelle séquence pour correspondre à l'ancienne séquence.

Questions connexes