9

トランザクションにある次のコードがあります。自分の仕事の単位をどこで/いつコミットすべきかわかりません。

わざと、私が使用している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

3 に答える 3

3

この質問に答えるための良い出発点は、エンタープライズアーキテクチャのパターンからの作業単位の定義です(http://martinfowler.com/eaaCatalog/unitOfWork.html):

ビジネストランザクションの影響を受けるオブジェクトのリストを維持し、変更の書き込みと同時実行の問題の解決を調整します。

作業単位の境界は、ビジネストランザクションの境界によって定義されます。この場合、これはデータベーストランザクションの境界と同義です(ただし、複数の要求にまたがる長期実行のビジネストランザクションの場合は、場合 )。

上記の定義から逆方向に作業し、示されているコードの一部についての私の理解に基づいて、ビジネストランザクション(#4)の最後に作業単位をコミットする必要があります。

余談ですが、データベーストランザクションスコープは常にUoWのスコープよりも小さくする必要があります(つまり、txスコープはUoW.Begin()とUoW.Commit()の呼び出しの間にあります)。UoWが複数のデータベーストランザクションにまたがっている場合、内部トランザクションの1つが失敗した場合は、補償トランザクションを使用してUoWを「リバランス」します。この場合、特にUoWがUoW.Begin()とUoW.Commit()で独自のデータベーストランザクション境界を作成している場合、これは単にコードに不要なノイズを追加しているため、トランザクションスコープを削除します。

于 2010-03-30T00:07:59.913 に答える
0

すべてのリポジトリへのすべての操作が行われた後、#4でコミットします。事前にコミットした場合、その呼び出し後に行われた変更はコミットされません。

于 2010-03-23T14:00:34.527 に答える
0

データストアがIDを割り当てていると仮定すると、#1をコミットする必要があり(NHibernateを使用すると、フラッシュする必要があります)、最後に#4をコミットする必要があります。

于 2010-03-29T23:18:48.623 に答える