0

継承したコードベースのために、かなり奇妙な要件があります。DAL はリポジトリ パターンに基づいていますが、一部のリポジトリは SqlConnection/SqlCommand を使用して直接 SQL とパラメーター化されたクエリを使用してコーディングされており、一部は NHibernate を使用してコーディングされています。

両方の分割からのリポジトリを必要とする一連のデータ操作を実行する必要があり、途中のいずれかの段階で失敗した場合は、すべてロールバックする必要があります。これについて最善の方法は何ですか?

System.Data は IDbTransaction を公開し、NHibernate は ITransaction を公開しますが、これら 2 つは互換性がありますか? 両方のトランザクションを同時に実行し、問題が発生した場合に両方をロールバックできますか? このシナリオで TransactionScope は役に立ちますか?

4

3 に答える 3

1

次のようなコードが必要だとします。

public class SomeService
{
    private readonly IRepositoryA _repoA;
    private readonly IRepositoryB _repoB;

    public void DoStuff(EntityA someEntityA, EntityB someEntityB)
    {
        try 
        {
             _repoA.Save(someEntityA);
             _repoB.Save(someEntityB);
             // commit all stuff here

        }
        catch
        {
             // rollback all stuff here
        }
    }
}

その場合は、両方のリポジトリが依存し、それぞれのトランザクション コンテキストを参照できる、ある種の UnitOfWork 抽象化が必要です。両方のリポジトリが Nhibernate または IDbConnection/DbTransactions を使用していれば、はるかに簡単ですが、混在しているため、もう少し作業を行う必要があります。

IDbTransaction と ITransaction の両方を収容する "GenericTransaction" を作成し、作業単位に新しい GenericTransaction を作成するメソッドを持たせる必要があります。

GenericTransaction のコミット/ロールバックは、2 つのトランザクションに対してそれぞれのアクションを実行します。

それを正しく行うには、既存のリポジトリをかなりリファクタリングする必要があります...しかし、他の方法はお勧めしません。

于 2012-10-05T14:21:03.390 に答える
1

TransactionScope は、ADO.Net を通過するすべてのコンポーネントで受け入れられるフックを作成します。すべての ORM は ADO.Net を通過するため、すべての ORM は暗黙的に TransactionScope を尊重します。NHibernate、Linq、EF、または選択した任意の ORM などのコードは、現在のスコープを新しいスコープで明示的にオーバーライドして TransactionScope を明示的に抑制しない限り、これを抑制できません。

複数の接続が登録されているため、サーバー上の分散トランザクションへのトランザクションのエスカレーションに問題がある可能性があります。これは、SQL Server/.Net のバージョンによって異なります。System.Transactions Integration with SQL Server を参照してください。

于 2012-10-05T14:19:48.917 に答える
1

nhibernate はsql ステートメントもサポートしています!

方法を覚えたようです

NHibernateSession.CreateSQLQuery、それはIQueryを返します(実際にはSQLQuery です)

そして、メソッドListまたはUniteResultを呼び出し続けることができます

通常、コーダーはHashtableという名前の kv クラスを好んで使用します。

Nhibernate で ITransaction を使用できます。

于 2012-10-05T13:50:45.913 に答える