В какой строке следующего кода я должен зафиксировать свою единицу работы?

StackOverflow https://stackoverflow.com/questions/2500305

Вопрос

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

Специально я не упомянул, какой тип 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();
}
Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top