- - PR -
SqlClientでの平行トランザクション方法を教えてください
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-01-29 17:57
SQLServer2005とVS2005で開発しています。
ある、コネクションに対してトランザクションAを開始し、 トランザクションAが終わるまでにその中でトランザクションBを開始、終了 することはできないのでしょうか? TranA開始 ↓ TranB開始 ↓ TranBコミット ↓ TranAコミット ちなみに、SQLConnectionは平行トランザクションを サポートしていないとエラーが出ます。 どなたかご存知の方がいらっしゃれば教えてください。 よろしくお願いいたします。 [ メッセージ編集済み 編集者: メガネ 編集日時 2007-01-29 18:13 ] | ||||
|
投稿日時: 2007-01-29 19:31
できますよ。
例えば以下のようにすれば、トランザクションAで行った更新処理はロールバックされますが、 トランザクションBで行った追加処理はコミットされます。
[ 関連リンク ] トランザクション スコープを使用した暗黙的なトランザクションの実装 TransactionScope クラス (System.Transactions) IsolationLevel 列挙体 (System.Transactions) | ||||
|
投稿日時: 2007-01-30 00:00
よこけんさん
ありがとうございます。 .NetFramework2.0からこういうのができるようになったんですね! 是非、試してみます!!★ | ||||
|
投稿日時: 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(); } | ||||
|
投稿日時: 2007-02-01 18:48
それは本来ありえないですね^^;
TransactionScopeでは、生成されてからDisposeされるまでの間にCompleteメソッドが呼び出されなかった場合、(アンビエントトランザクションのDisposeのタイミングで)ロールバックが行われます。また、Completeメソッド=コミットではないことに注意してください。 scopeAのCompleteメソッドが呼び出されない以上、 データ更新処理Aのコミットが行われることはありません。 恐らくコーディングミスか確認ミスかと思います。 ちなみに、その例だと「データ更新処理Aはコミットされない」ではなく、「データ更新処理Aとデータ更新処理Cはコミットされない」ということになります。 | ||||
|
投稿日時: 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を正常終了させません!!"); } | ||||
|
投稿日時: 2007-02-03 14:23
コネクションを明示的にオープン・クローズしてるということは
接続型データアクセス方式ですか? ( DataReaderを使う方法 ) こちらでも確認しましたが、 非接続型データアクセス方式 ( DataAdapterやTableAdapterを使う方法 ) の場合問題ありません。 しかし、コネクションを明示的にオープン・クローズするようにしたら、同様の現象が発生しました。 ただ、コネクションのオープン・クローズを以下のように行えば問題は発生しません。
おそらく、トランザクションスコープの内側で開かれたコネクションに対してでなければ、新しいトランザクションを開始することができないのでしょう。 |
1