106

いくつかのオブジェクトをデータベースに挿入し、メソッドがそれらのオブジェクトを取得するかどうかを確認する統合テストを書いています。

私のデータベースへの接続はNHibernateを介しています...そして、そのようなテストを作成する私の通常の方法は、次のことを行うことです:

NHibernateSession.BeginTransaction();

//use nhibernate to insert objects into database
//retrieve objects via my method
//verify actual objects returned are the same as those inserted

NHibernateSession.RollbackTransaction();

しかし、私は最近、明らかにこの目的に使用できるTransactionScopeについて知りました...

私が見つけたコード例は次のとおりです。

public static int AddDepartmentWithEmployees(Department dept)
{

    int res = 0;

    DepartmentAdapter deptAdapter = new DepartmentAdapter();
    EmployeeAdapter empAdapter = new EmployeeAdapter();
    using (TransactionScope txScope = new TransactionScope())
    {

        res += deptAdapter.Insert(dept.DepartmentName);
        //Custom method made to return Department ID 
        //after inserting the department "Identity Column"
        dept.DepartmentID = deptAdapter.GetInsertReturnValue();
        foreach(Employee emp in dept.Employees)
        {

            emp.EmployeeDeptID = dept.DepartmentID;
            res += empAdapter.Insert(emp.EmployeeName, emp.EmployeeDeptID);

        }
        txScope.Complete();

    }
    return res;

}

txScope.Complete()挿入されたデータがロールバックされる行を含めないと、私は信じています。しかし、残念ながら、それがどのように可能であるかはわかりません...オブジェクトは、オブジェクトとオブジェクトのトランザクションをデータベース上でどのようtxScopeに追跡しますか。deptAdapterempAdapter

ここで少し情報が不足しているように感じます...を使用してコードを囲むことで、 BeginTransaction()and ) 呼び出しを本当に置き換えることができますか?RollbackTransaction(TransactionScope

TransactionScopeそうでない場合、トランザクションをロールバックするためにどのように機能しますか?

4

2 に答える 2

115

基本的に、TransactionScope はアダプタを追跡しません。データベース接続を追跡します。DB 接続を開くと、接続はアンビエント トランザクション (トランザクション スコープ) があるかどうかを調べ、存在する場合はそれに参加します。同じ SQL サーバーへの複数の接続がある場合、これは分散トランザクションにエスカレートすることに注意してください。

using ブロックを使用しているため、例外が発生した場合でも dispose が確実に呼び出されるようになります。したがって、txScope.Complete() の前に dispose が呼び出された場合、TransactionScope は接続にトランザクション (または DTC) をロールバックするように指示します。

于 2009-01-30T05:49:11.797 に答える
57

このTransactionScopeクラスは、スレッド固有のクラスで Transaction動作します。

が作成されると、スレッドTransactionScopeに があるかどうかがチェックされます。Transaction存在する場合はそれを使用し、存在しない場合は新しいものを作成してスタックにプッシュします。

既存のものを使用する場合は、リリースのカウンターをインクリメントするだけです (それを呼び出す必要があるためDispose)。最後のリリースでTransactionコミットされていない場合、すべての作業がロールバックされます。

クラスが魔法のようにトランザクションについて知っているように見える理由については、このモデルを使用したいクラスの実装の詳細として残されています。

deptAdapterおよびインスタンスを作成すると、スレッド上に現在のトランザクション (クラスの静的プロパティ)emptAdapterがあるかどうかがチェックされます。存在する場合、それ自体を に登録して、コミット/ロールバック シーケンスに参加します (カーネル、分散型などのさまざまなトランザクション コーディネーターを制御し、伝播する可能性があります)。CurrentTransactionTransactionTransaction

于 2009-01-30T05:50:03.043 に答える