- - PR -
Transact-SQLでのトランザクション管理について
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-12-09 14:04
どうもこんにちは。
このプログラムですと、ループ内の登録処理でエラーが発生した場合、その時点でロールバックします。 1度ロールバックをしていますので、ERRFLG=1なので再度ロールバックを行おうとそてもROLLBACK TRANSACTIONに対するBEGIN TRANSACTIONがないため、ロールバック処理が行われません。 結果、ストアドが終了すると暗黙的にコミット処理が行われてしまいます。 (クエリアナライザで実行すると、エラーメッセージが表示されるはずです。) 回避策として、ラベルを使用して、文末にコミット処理をしてみたらどうでしょうか。 (中略) SET @ERRFLG = 1 BEGIN (エラー出力) GOTO Error END (中略) IF @@ERROR <> 0 GOTO Error (中略) で、一番最後にERRFLGで判定する処理の代わりに COMMIT TRAN RETURN 0 Error: ROLLBACK TRAN RETURN 1 ざっとこんな感じです。 | ||||||||
|
投稿日時: 2005-12-09 14:29
begin transaction で 1度しか明示的トランザクションを開始していないのに、ループの中で複数回 rollback transaction が呼ばれているのが原因じゃないかな。
1度目の rollback transaction で明示的トランザクションが終了するので、SQL Server は自動コミットモードに戻ってしまう。自動コミットモードだと、ステートメント単位で自動的にコミットされるので、全体としてみるとデータが戻らないという症状になる。 根本的な解決策は、トランザクションの開始数と終了数を合わせること。自分で @@ERROR を判定してフロー制御して数合わせしてもいいけど、それよりも SET XACT_ABORT ON を指定して厳密なトランザクションにしておいたほうが楽だし安心できると思います。@@ERROR を判定する必要もなくなるし。 | ||||||||
|
投稿日時: 2005-12-09 17:16
返答が遅れてしまいました。
すみません。Transact-SQLでのコーディングが初めてなので教えて 下さい。 Transact-SQLでは変数へ値をセットする方法として、SELECT文を 使用するのが一般的なのでしょうか。 MSサイトなどを見ていると、SETを用いた記述が例文として挙げられて います(勿論SELECT文を用いた形もあります)。 PL/SQLでは代入演算子":="を用いますので、同じノリでSETを使用して いました。 もしこのような"定石"的な記述方法があれば、また教えてください。 先のご指摘も非常に参考になりました。 | ||||||||
|
投稿日時: 2005-12-09 17:33
unibonさん
コメント有難うございました。
ご指摘の通りプロシージャはDTSツール上のActiveX(VBScript)からADO経由で呼び出して います。 osqlを使用しても現象は変わりませんでした。やはりループ回数分(1件処理されました) と表示されます。
ご指摘頂いた通り、START TRANSACTION、COMMIT TRANSACTION、ROLLBACK TRANSACTION全て外してみましたが、結果は変わらずループの度にコミットされていました。 また、単純にFETCHしてINSERTするのみ、エラー処理も何もしないプロシージャも同じ結果でした。 | ||||||||
|
投稿日時: 2005-12-09 17:44
GUCCHIさん
ご回答ありがとうございました。
ご指摘頂いたコードは後で試して、結果を報告します(ちょっと今時間が とれないので)。 ただ、下記に記載したようにROLLBACK文を一つも記載しないシンプルな カーソルループ文(ループの中ではINSERTのみです)を実行しても、やはり ループ毎にコミットされているようです。 | ||||||||
|
投稿日時: 2005-12-09 17:49
コメント有難うございました。
このような事情があったのですか・・ BOOKS ONLINEを見てみたのですがSET XACT_ABORT ONは確かに一番安全かもしれません ね。後で試してみて、また報告します。 有効な情報誠に有難うございました。 | ||||||||
|
投稿日時: 2005-12-09 18:01
らいです。
あ、別に一般的ではないですよ?(多分) や、私の場合はじめてみた参考書(のようなもの)に SELECT 変数=〜 ってなってたので今でも使ってるだけで。 # SETはSQL文の環境設定用だと長い間思っていたので。(汗 # おかげで未だにあまり使用しません。(笑) 何か明示的な理由があるのかな〜と思って聞いてみただけです。 他意はありませんのでご容赦を。 _________________ 一寸先は闇 安定してるシステムって言ったじゃん(泣) | ||||||||
