0

ソースデータベースから宛先データベースへのインポートプロセスを実行しています。これらのインポートを自動化された方法で頻繁に実行する必要があります。

ソースは宛先とは別のサーバーにあります。どちらもMSSQL2008です。Linq2SQLを使用してソースにアクセスし、カスタムデータレイヤーを使用して宛先にアクセスします。ソースDBを変更することはありません(ただし、現時点では読み取り専用として復元していません)。ただし、現在、transactionScope内でインポートを実行すると、別々のサーバー上の2つのDBにアクセスするため、トランザクション全体がDTCにプロモートされます。

ソースDBを読み取り専用にした場合でも、これは実行されますか?

このシナリオでDTCプロモーションを回避する方法に関する他の提案はありますか?

Remusの回答に対するフォローアップの質問(ありがとう):

フォローアップ#1:私のインポートルーチンは、ソースからレコードをインポートし、宛先に新しいレコードを作成するように構成されています。このような:

using(var scope = new TransactionScope())
{
   // read some from source db using Linq2Sql
   // transform source info
   // update destination

   // read some more from source db using Linq2Sql
   // transform source info
   // update destination

}

TransactionScopeのLinq2SqlビットをRequiresNewで囲むと言っていますか?または、私はソースでのトランザクションを本当に気にしないので、トランザクションにその接続が含まれるようにSuppressを使用してTransactionScopeで囲むことができますよね?

フォローアップ#2:

「同じデータベースに対しても、2番目の接続を開く」と言うと、これに関するいくつかのバリエーションを読みました。

  1. "second connection" ==まったく同じ接続文字列であっても、Connectionオブジェクトの2番目のインスタンス
  2. "2番目の接続"==別のResourceManagerへの接続およびSQL2005で、これ以前は上記の1と同じ意味ですが、SQL2008では、これは別のインスタンスを意味します(つまり、同じインスタンス上の2つのDBは昇格されません)
4

1 に答える 1

2

トランザクションスコープ内で2番目のADO.Net接続を開くと、両方の接続がDTCにプロモートされます。同じDBへの新しい接続であっても、問題ではありません。データベースの読み取り専用性もそれとは何の関係もなく、それとは何の関係もあり得ませんでした。まず、接続は開いた後にデータベースを変更できるため、データベース固有ではありません。次に、読み取り専用データベースは多くの書き込みを実行できます(たとえば、readonlydb.dbo.myProcedureを呼び出すことができ、プロシージャ内でwritabledb.dbo.tableを更新できます)。

DTCを回避したい場合は、2つのアクセスレイヤー間で異なるトランザクションスコープを使用する必要があります(つまり、RequireNewで新しいスコープを作成します)。

アップデート

スコープ外で読み取りを行うことが可能であれば、それは完璧です。

// read some from source db using Linq2Sql 
// read some more from source db using Linq2Sql 
using(var scope = new TransactionScope()) 
{ 
   // transform source info 
   // update destination 

   // transform source info 
   // update destination 
} 

おそらく、2番目の読み取りセットは、通常、最初の変換/更新の結果に依存しているため、これはほとんどありそうにないことを理解しています。したがって、読み取りを行うときは、スコープを抑制するのが最適です。

using(var scope = new TransactionScope()) 
{ 
   using(var nada= new TransactionScope(TransactionScopeOption.Supress))
   {
       // read some from source db using Linq2Sql 
       // transform source info 
   }
   // update destination 

   using(var nada= new TransactionScope(TransactionScopeOption.Supress))
   {
       // read some more from source db using Linq2Sql
       // transform source info 
   } 
   // update destination 
} 

ところで、「linqを使用してデータを読み取る」とは、クエリ式を作成して後でその式を使用するだけでなく、実際にクエリを列挙することを意味すると思います。トランザクションスコープがクエリ式とどのように相互作用するかは正確にはわかりませんが、スコープは宣言ではなくクエリの実行に適用されると想定しています。

于 2010-01-14T18:44:23.700 に答える