Pregunta

I tiene el siguiente código que está en una transacción. No estoy seguro de dónde / cuando debería estar cometiendo mi unidad de trabajo.

A propósito, he no menciona qué tipo de Respoistory que estoy usando - por ejemplo. LINQ to SQL, Entity Framework 4, NHibernate, etc.

Si alguien sabe dónde, que pueden explique por qué se han dicho, ¿dónde? (Estoy tratando de entender el patrón a través del ejemplo (s), en lugar de sólo conseguir el código para trabajar).

Esto es lo que tengo: -

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();
}
¿Fue útil?

Solución

Commit en el # 4 después de todas las operaciones se realizan a todos los repositorios. Si se compromete de antemano, los cambios realizados después de esa llamada no están comprometidos.

Otros consejos

Un buen punto de partida para responder a esta pregunta es la definición de la unidad de trabajo de los patrones de la arquitectura empresarial ( http://martinfowler.com/eaaCatalog/unitOfWork.html ):

  

Mantiene una lista de los objetos afectados por una transacción de negocios y coordina la escritura de los cambios y la resolución de problemas de concurrencia.

Los límites de su unidad de trabajo se define por los límites de su transacción de negocios - en este caso, que es sinónimo de los límites de la transacción de base de datos (pero en el caso de una transacción de negocios de larga duración que abarca múltiples peticiones que puedan no ser el caso).

revés de trabajo de la definición anterior y en base a mi entendimiento de la pieza de código que se muestra, se debe comprometer a la unidad de trabajo al final de la transacción comercial (# 4).

Como un aparte, sus ámbitos de transacción base de datos debería ser siempre menor que el alcance de su UoW (es decir, reside el alcance tx entre la llamada a UoW.Begin () y UoW.Commit ()). Si las transacciones de bases de datos múltiples UoW su vanos que usarían una transacción de compensación a "reequilibrar" la UoW si una de las transacciones internas fallidos. En este caso, y sobre todo si su UoW está creando es poseer límites de la transacción de base de datos en UoW.Begin () y UoW.Commit () Me gustaría quitar el ámbito de transacción ya que esto es simplemente agregar ruido innecesario al código.

Si se asume que el almacén de datos es la asignación de identificadores de, usted tiene que comprometerse # 1 (con NHibernate incluso se debe al ras), entonces al final # 4.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top