На какой строке в следующем коде я должен зафиксировать свою единицу работы? - PullRequest
9 голосов
/ 23 марта 2010

У меня есть следующий код, который находится в транзакции. Я не уверен, где и когда мне следует отдавать свою единицу работы.

Специально, я не упомянул, какой тип Respoistory я использую - например. Linq-To-Sql, Entity Framework 4, NHibernate и т. Д.

Если кто-то знает где, могут ли они объяснить, ПОЧЕМУ они сказали, где? (Я пытаюсь понять шаблон с помощью примера (ов), а не просто заставить мой код работать).

Вот что у меня есть: -

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

Ответы [ 3 ]

3 голосов
/ 30 марта 2010

Хорошей отправной точкой для ответа на этот вопрос является определение Единицы работы из шаблонов архитектуры предприятия (http://martinfowler.com/eaaCatalog/unitOfWork.html):

Поддерживает список объектов, затронутых бизнес-транзакцией, и координирует выписывание изменений и решение проблем параллелизма.

Границы вашей единицы работы определяются границами вашей бизнес-транзакции - в этом случае это синоним границ транзакции базы данных (но в случае длительной бизнес-транзакции, которая охватывает несколько запросов, которые могут не будь так).

Работая в обратном направлении от приведенного выше определения и основываясь на моем понимании показанного фрагмента кода, вы должны зафиксировать единицу работы в конце бизнес-транзакции (# 4).

Кроме того, объемы ваших транзакций базы данных всегда должны быть меньше, чем область вашего UoW (т.е. область tx находится между вызовом UoW.Begin () и UoW.Commit ()). Если ваш UoW охватывает несколько транзакций базы данных, вы должны использовать компенсирующую транзакцию, чтобы «сбалансировать» UoW, если одна из внутренних транзакций потерпела неудачу. В этом случае, особенно если ваш UoW создает собственные границы транзакций базы данных в UoW.Begin () и UoW.Commit (), я бы удалил область транзакции, так как это просто добавляет ненужный шум в код.

0 голосов
/ 30 марта 2010

Предполагая, что ваше хранилище данных назначает идентификаторы, вы должны зафиксировать # 1 (с NHibernate вы должны даже очистить), затем в конце # 4.

0 голосов
/ 23 марта 2010

Подтвердите в # 4 после выполнения всех операций со всеми хранилищами. Если вы фиксируете заранее, изменения, сделанные после этого вызова, не фиксируются.

...