Domanda

Ho il seguente codice che si trova in una transazione. Non sono sicuro di dove / quando dovrei commettere mia unità di lavoro.

In proposito, non ho menzionato che tipo di repositorio sto usando - ad es. LINQ to SQL, Entity Framework 4, NHibernate, ecc.

Se qualcuno sa dove, possono spiegare perché hanno detto, dove? (Sto cercando di capire il modello con l'esempio (s), al contrario di solo ottenere il mio codice per funzionare).

Ecco quello che ho: -

using
(
    TransactionScope transactionScope =
        new TransactionScope
        (
            TransactionScopeOption.RequiresNew,
            new TransactionOptions
                { IsolationLevel = IsolationLevel.ReadUncommitted }
        )
)
{
    _logEntryRepository.InsertOrUpdate(logEntry);
    //_unitOfWork.Commit();  // Here, commit #1 ?

    // Now, if this log entry was a NewConnection or an LostConnection,
    // then we need to make sure we update the ConnectedClients.
    if (logEntry.EventType == EventType.NewConnection)
    {
        _connectedClientRepository.Insert(
            new ConnectedClient { LogEntryId = logEntry.LogEntryId });
        //_unitOfWork.Commit(); // Here, commit #2 ?
    }

    // A (PB) BanKick does _NOT_ register a lost connection,
    // so we need to make sure we handle those scenario's as a LostConnection.
    if (logEntry.EventType == EventType.LostConnection ||
        logEntry.EventType == EventType.BanKick)
    {
        _connectedClientRepository.Delete(
            logEntry.ClientName, logEntry.ClientIpAndPort);
        //_unitOfWork.Commit(); // Here, commit #3 ?
    }

    _unitOfWork.Commit(); // Here, commit #4 ?
    transactionScope.Complete();
}
È stato utile?

Soluzione

Impegnarsi al # 4, dopo tutte le operazioni a tutti i repository sono fatti. Se si commettono in anticipo, le modifiche apportate dopo quella telefonata non sono impegnati.

Altri suggerimenti

Un buon punto di partenza per rispondere a questa domanda è la definizione di unità di lavoro da modelli di Enterprise Architecture ( http://martinfowler.com/eaaCatalog/unitOfWork.html ):

  

mantiene un elenco di oggetti interessati da una transazione commerciale e coordina la scrittura di modifiche e la risoluzione dei problemi di concorrenza.

I confini della vostra unità di lavoro sono definite dai confini della vostra transazione commerciale - in questo caso che è sinonimo dei confini della transazione database (ma nel caso di una transazione commerciale lunga corsa che si estende su più richieste che possono non essere il caso).

Andando a ritroso dalla definizione di cui sopra e in base alla mia comprensione del pezzo di codice mostrato, si dovrebbero impegnare le unità di lavoro al termine della transazione commerciale (# 4).

Per inciso, gli ambiti delle transazioni del database deve essere sempre inferiore alla portata del vostro UoW (vale a dire l'ambito tx risiede tra la chiamata a UoW.Begin () e UoW.Commit ()). Se il vostro UoW si estende su più transazioni di database è necessario utilizzare una transazione di compensazione per "riequilibrare" l'UoW se una delle transazioni interne fallito. In questo caso, e soprattutto se il vostro UoW sta creando è di possedere i limiti delle transazioni del database a UoW.Begin () e UoW.Commit () Vorrei rimuovere l'ambito transazione come questo è semplicemente l'aggiunta di rumore inutile il codice.

Supponendo che il tuo negozio di dati sta assegnando gli ID, è necessario impegnarsi # 1 (con NHibernate si dovrebbe anche flush), poi alla fine # 4.

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