Question

Je suis en train de comprendre la manière correcte d'incrémenter atomiquement un compteur dans une table et utiliser cette valeur augmente comme un affichage uniquement pseudo ID pour un enregistrement dans un autre.

Ce que j'est une table de sociétés et d'une table de travail. Je veux que chaque entreprise d'avoir son propre ensemble de job_numbers. J'ai un job_id d'incrémentation automatique, mais ces chiffres sont partagés entre toutes les entreprises. à savoir: le nombre d'emplois devraient augmenter en général sans lacunes pour chaque entreprise

.

-à-dire:

  • les entreprises (company_id, next_job_number)
  • Offres d'emploi (company_id, job_id, job_number)

Actuellement, je fais cela (comme méthode de la classe d'emploi partiel):

public void SaveJob()
{
    using (var scope = new System.Transactions.TransactionScope())
    {
        if (job_id == 0)
        {
            _db.Update<company>()
                .SetExpression("next_job_number").EqualTo("next_job_number+1")
                .Where<company>(x => x.company_id == company_id)
                .Execute();

            company c = _db.companies.SingleOrDefault(x => x.company_id == company_id);

            job_number = c.next_job_number;
        }

        // Save the job
        this.Save();

        scope.Complete();
    }
}

Il semble fonctionner, mais je ne sais pas s'il y a des pièges ici? On se sent mal, mais je ne sais pas comment d'autre de le faire.

Un conseil apprécié.

Était-ce utile?

La solution

Tout d'abord,

vous devez utiliser TransactionScope en conjonction avec un SharedDbConnectionScope ou votre transaction ne fonctionnera pas comme prévu.

En second lieu,

J'utiliser une autre approche avec une seule déclaration et sans la nécessité de sauver le job_id avec la société)

  1. Save the record avec job_number = 0

  2. Mettre à jour le record avec quelque chose comme ceci

    UPDATE JOBS SET = job_number     (SELECT MAX (job_number) 1 à partir des emplois où company_id = 12345)     Où job_id = "+ this.job_id;

(Vous ne devez convertir cette requête à la syntaxe subsonique, je ne l'utilise subsonic3) Cela devrait garantir que le nombre d'emplois est unique pour chaque entreprise (si vous enveloppez à la fois la commande de sauvegarde et mise à jour dans une transaction et utiliser un verrou de table).

Autres conseils

En utilisant le code dynamique pour obtenir la plus grande valeur actuelle peut être risqué (les valeurs en double potentiels) sur un système multi-utilisateurs de haut volume.

Une autre approche pourrait être de créer une nouvelle table avec deux colonnes; un caractère PK, et l'autre un nombre entier pour stocker la dernière valeur pertinente. Chaque fois que vous voulez une nouvelle valeur, augmenter la valeur dans le dossier de la société concernée et utiliser cette valeur pour votre numéro de commande. Le caractère PK comprendrait quelque chose comme:

"LAST_ORDER_NUMBER_COMPANY_" + company_id

J'ai une procédure stockée à l'appel qui démarre soit automatiquement un nouveau record la première fois qu'une société a un ordre, ou incrémente pour les commandes ultérieures, et renvoie la nouvelle valeur de retour du numéro de commande.

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