Domanda

Sto cercando di capire il modo corretto per incrementare atomicamente un contatore in una tabella e utilizzare quel valore incrementato come ID pseudo di sola visualizzazione per un record in un'altra.

Quello che ho è una tabella delle aziende e una tabella dei lavori.Voglio che ogni azienda abbia il proprio set di job_numbers.Ho un job_id con incremento automatico, ma questi numeri sono condivisi tra tutte le aziende.cioè:i numeri di posti di lavoro dovrebbero generalmente aumentare senza lacune per ciascuna azienda.

cioè:

  • aziende(company_id, next_job_number)
  • lavori(id_azienda, id_lavoro, numero_lavoro)

Attualmente sto facendo questo (come metodo sulla classe di lavoro parziale):

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();
    }
}

Sembra funzionare, ma non sono sicuro che ci siano delle insidie ​​​​qui?Sembra semplicemente sbagliato, ma non sono sicuro di come altro farlo.

Qualsiasi consiglio apprezzato.

È stato utile?

Soluzione

Primo,

dovresti utilizzare TransactionScope insieme a SharedDbConnectionScope altrimenti la transazione non funzionerà come previsto.

Secondo,

Utilizzerei un altro approccio con una singola istruzione e senza la necessità di salvare job_id con l'azienda)

  1. Salva il record con job_number = 0

  2. Aggiorna il record con qualcosa di simile

    AGGIORNA I PROCESSI IMPOSTATI JOB_NUMBER = (SELEZIONARE MAX(job_number)+1 DAI LAVORI IN CUI company_id = 12345) DOVE job_id = " + this.job_id;

(Hai solo bisogno di convertire questa query in sintassi subsonica, io non uso subsonic3) In questo modo si dovrebbe garantire che il numero di processo sia univoco per ogni società (se si esegue il wrapping di entrambi i comandi save e update in una transazione e si utilizza un blocco di tabella).

Altri suggerimenti

L'utilizzo del codice dinamico per ottenere il valore più alto corrente può essere rischioso (potenziali valori duplicati) su un sistema multiutente ad alto volume.

Un altro approccio potrebbe essere quello di creare una nuova tabella con due colonne;uno è un carattere PK e l'altro un numero intero per memorizzare l'ultimo valore rilevante.Ogni volta che desideri un nuovo valore, incrementa il valore nel record della società pertinente e utilizza tale valore per il numero dell'ordine.Il carattere PK comprenderebbe qualcosa del tipo:

"LAST_ORDER_NUMBER_COMPANY_" + company_id

Ho una procedura memorizzata da chiamare che avvia automaticamente un nuovo record la prima volta che un'azienda riceve un ordine o lo incrementa per gli ordini successivi e restituisce il nuovo valore del numero dell'ordine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top