- PR -

SqlClientでの平行トランザクション方法を教えてください

1
投稿者投稿内容
メガネ
会議室デビュー日: 2006/06/30
投稿数: 9
投稿日時: 2007-01-29 17:57
SQLServer2005とVS2005で開発しています。
ある、コネクションに対してトランザクションAを開始し、
トランザクションAが終わるまでにその中でトランザクションBを開始、終了
することはできないのでしょうか?
TranA開始
  ↓
 TranB開始
  ↓
 TranBコミット
  ↓
TranAコミット

ちなみに、SQLConnectionは平行トランザクションを
サポートしていないとエラーが出ます。

どなたかご存知の方がいらっしゃれば教えてください。
よろしくお願いいたします。


[ メッセージ編集済み 編集者: メガネ 編集日時 2007-01-29 18:13 ]
よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2007-01-29 19:31
できますよ。
例えば以下のようにすれば、トランザクションAで行った更新処理はロールバックされますが、
トランザクションBで行った追加処理はコミットされます。

コード:
TransactionOptions scopeAoption = new TransactionOptions();
scopeAoption.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;

using (TransactionScope scopeA = new TransactionScope(TransactionScopeOption.Required, scopeAoption));
{
  // データ更新処理

  using (TransactionScope scopeB = new TransactionScope(TransactionScopeOption.RequiresNew))
  {
    // データ追加処理
    scopeB.Complete();
  }
  // サンプルなのでコメントアウト
  // scopeA.Complete();
}



[ 関連リンク ]
トランザクション スコープを使用した暗黙的なトランザクションの実装
TransactionScope クラス (System.Transactions)
IsolationLevel 列挙体 (System.Transactions)
メガネ
会議室デビュー日: 2006/06/30
投稿数: 9
投稿日時: 2007-01-30 00:00
よこけんさん

ありがとうございます。
.NetFramework2.0からこういうのができるようになったんですね!
是非、試してみます!!★
メガネ
会議室デビュー日: 2006/06/30
投稿数: 9
投稿日時: 2007-02-01 17:52
お世話になります。

以下の場合に☆throw new Exception☆があるため、
データ更新処理Aのみコミットされない認識だったんですが、
なぜかコミットされてしまいます・・・。

TransactionOptions scopeAoption = new TransactionOptions();
scopeAoption.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;

using (TransactionScope scopeA = new TransactionScope(TransactionScopeOption.Required, scopeAoption));
{
データ更新処理A

using (TransactionScope scopeB = new TransactionScope(TransactionScopeOption.RequiresNew))
{
  データ更新処理B
// コミット?
scopeB.Complete();
}

using (TransactionScope scopeC = new TransactionScope(TransactionScopeOption.RequiresNew))
{
  ☆throw new Exception☆
}
// コミット?
scopeA.Complete();
}

よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2007-02-01 18:48
それは本来ありえないですね^^;

TransactionScopeでは、生成されてからDisposeされるまでの間にCompleteメソッドが呼び出されなかった場合、(アンビエントトランザクションのDisposeのタイミングで)ロールバックが行われます。また、Completeメソッド=コミットではないことに注意してください。
scopeAのCompleteメソッドが呼び出されない以上、 データ更新処理Aのコミットが行われることはありません。
恐らくコーディングミスか確認ミスかと思います。

ちなみに、その例だと「データ更新処理Aはコミットされない」ではなく、「データ更新処理Aとデータ更新処理Cはコミットされない」ということになります。
メガネ
会議室デビュー日: 2006/06/30
投稿数: 9
投稿日時: 2007-02-02 10:03
よこけんさん

ありがとうございます。

TransactionScopeの入れ子の中でコネクションをオープンすると、
勝手にコミットされる問題が解決しました。

しかし、同一のコネクションでscopeB内でデータ追加すると、
scopeBはCompleteメソッドが走って、コミットされるはずなのに
データ更新処理A、データ更新処理B両方ロールバックされてしまいます。
なので、以下のようにスコープ毎にコネクションを
張ってやることで解決していますが、
同一コネクションですべて任せるのはできないのでしょうか?
トランザクションの分離レベルの問題かと思い試してみましたが
やはりうまくいきませんでした。


TransactionOptions scopeAoption = new TransactionOptions();
scopeAoption.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;

using (TransactionScope scopeA = new TransactionScope(TransactionScopeOption.Required, scopeAoption));
{
// コネクションAオープン
// データ更新処理A

using (TransactionScope scopeB = new TransactionScope(TransactionScopeOption.RequiresNew))
{
// コネクションBオープン
// データ更新処理B
// コネクションBクローズ
scopeB.Complete();
}

throw New Exception("データ更新処理Aを正常終了させません!!");
}

よこけん
大ベテラン
会議室デビュー日: 2006/01/31
投稿数: 216
投稿日時: 2007-02-03 14:23
コネクションを明示的にオープン・クローズしてるということは
接続型データアクセス方式ですか? ( DataReaderを使う方法 )

こちらでも確認しましたが、
非接続型データアクセス方式 ( DataAdapterやTableAdapterを使う方法 ) の場合問題ありません。
しかし、コネクションを明示的にオープン・クローズするようにしたら、同様の現象が発生しました。
ただ、コネクションのオープン・クローズを以下のように行えば問題は発生しません。

コード:
TransactionOptions scopeAoption = new TransactionOptions();
scopeAoption.IsolationLevel = System.Transactions.IsolationLevel.RepeatableRead;

using (TransactionScope scopeA = new TransactionScope(TransactionScopeOption.Required, scopeAoption));
{
    // コネクションAオープン
    // データ更新処理A
    // コネクションAクローズ
    using (TransactionScope scopeB = new TransactionScope(TransactionScopeOption.RequiresNew))
    {
        // コネクションAオープン
        // データ更新処理B
        // コネクションAクローズ
        scopeB.Complete();
    }

    throw New Exception("データ更新処理Aを正常終了させません!!");
}



おそらく、トランザクションスコープの内側で開かれたコネクションに対してでなければ、新しいトランザクションを開始することができないのでしょう。
1

スキルアップ/キャリアアップ(JOB@IT)