0

私は明らかにここで何か間違ったことをしています。NHibernateがこのシナリオで何かをコミットしようとしている理由がわかりません。

長さが200文字を超える「説明」フィールドを指定しました。私は呼ばれるバリデーターを持っています:

Order.ValidateAndThrow(Order);
RuleFor(order => order.Description).Length(0, 200).WithName("Description");

説明の長さが200文字を超えているため、ValidateAndThrowは例外をスローします。

例外を処理するcatchブロックは次のとおりです。

catch (Exception exception)
{
    Logger.Error(exception);
    NHibernateSessionManager.Instance.RollbackTransaction();
    throw;
}

public void RollbackTransaction()
{
    ITransaction transaction = ContextTransaction;

    try
    {
        if (HasOpenTransaction())
        {
            transaction.Rollback();
        }

        ContextTransaction = null;
    }
    finally
    {
        CloseSession();
    }
}

/// <summary>
/// Flushes anything left in the session and closes the connection.
/// </summary>
public void CloseSession()
{
    ISession session = ContextSession;

    if (session != null && session.IsOpen)
    {
        session.Flush();
        session.Close();
    }

    ContextSession = null;
}

つまり、transaction.Rollback()ステートメントが正常に実行されてから、CloseSession()が呼び出されることがわかります。

CloseSession()内で、session.Flush()が実行されます。これにより、私の注文エンティティは、明らかに、データベースに保存されようとします。でも、変更をロールバックしたばかりだと思いましたか?

それでも、SessionClose()を呼び出すとGenericADOExceptionが生成されます。内部例外メッセージは次のようになります"{"String or binary data would be truncated.\r\nThe statement has been terminated."}"

このシナリオでトランザクションを適切に終了するにはどうすればよいですか?

4

1 に答える 1

1

ここのドキュメントによると

ITransaction APIを使用している場合は、この手順[セッションのフラッシュ]について心配する必要はありません。トランザクションがコミットされると、暗黙的に実行されます。

したがって、NHibernateを使用している場合はITransaction.Commit()、フラッシュする必要はありません。また、トランザクションがロールバックされた場合は、フラッシュしたくないことは間違いありません。常にセッションを閉じるようにしてください。

于 2013-02-08T20:36:46.193 に答える