- - PR -
sqlExceptionとDBConcurrencyExceptionについて
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-03-30 17:14
いつもお世話になっております。
ADO.NETとC#を用いてWindowsアプリケーションを作成しています。 DBはSQL SERVER2000 です。 同時実行をした場合のエラー処理について質問させてください。 例) 次のTABLE1を更新します。 取得時 tbl_id | name | 1 A 2 B 3 C tbl_idが1のnameを次のように変更して登録します。 tbl_id | name | 1 AA 2 B 3 C 更新には次のようなプロシージャを用意しました。 CREATE PROCEDURE updateTABLE1 ( @tbl_id int , @name char(10), @Orijinal_tbl_id int, @Orijinal_name char(10) ) AS DECLARE @upd_error int SET @upd_error = @@ERROR UPDATE TABLE1 SET name = @name WHERE (tbl_id = @Orijinal_tbl_id ) AND ( name = @Orijinal_name ) SET @upd_error = @@ERROR IF @upd_error != 0 RAISERORR( 50001, 16, 1 ) RETURN @@ERROR 故意に同時実行になるようにテストしているのですが、 必ずDBConcurrencyExceptionにスローされてしまいます。 SQL SERVERが出した警告やエラーはsqlExeptionにスローしてほしいのですが そうはならないのでしょうか? (この同時実行違反のエラーもSQL SERVERから出されてると解釈しています) ※そもそも、sqlExeptionとDBConcurrencyExceptionが区別されている理由が よくわからないのです。 SQL SERVERが警告またはエラーを返したときにスローされるのがsqlExeptionであるな らば、sqlExeptionで統一しても良いのでは?と思うのですが。。。 長々とすみません。 よろしくお願いいたします。 | ||||||||
|
投稿日時: 2005-03-30 17:31
ヘルプを見る限り
DBConcurrencyExceptionはSQL ServerではなくDataAdapterがスローすると書かれていますが、 DataAdapterを使用されているのでしょうか? | ||||||||
|
投稿日時: 2005-03-30 17:32
まず、osqlで、更新する行が0になるようなUPDATE文を実行してみてください。
エラーになりましたか?なりませんね。これより、このエラーはデータベースに起因するものではないことが理解できると思います。 次に、MSDNの、DBConcurrencyExceptionクラスのページをみます。ここに、例外の派生元が書かれています。この中にSqlExceptionが入っていますか?いませんね。 このページの説明をよく読むと、こう書いてあります。
SqlCommand.Execute*メソッドでも、例外はでず、更新された行が0と返ってくるだけです。この例外は、DataAdapterが生成するものです。 [ メッセージ編集済み 編集者: Jitta 編集日時 2005-03-30 17:34 ] | ||||||||
|
投稿日時: 2005-03-31 11:18
burton999さん、Jittaさんお返事ありがとうございました。
確かに更新にDataAdapterを使用しています。 以下のようにエラー処理していました。 try { dataAdapter.Update( dataSet ); } catch( sqlExeption sqlerr ) { Console.WriteLine( sqlerr.Message ); } catch( DBConcurrencyException dberr ) { Console.WriteLine( dberr.Message ); } catch( Exception exerr ) { Console.WriteLine( exerr.Message ); } Jittaさんがおっしゃるとおり、 更新する行が0になるようなUPDATE文を実行してみましたが 確かにエラーにはなりませんでした。 つまり私が作成した更新プロシージャで IF @upd_error != 0 RAISERORR( 50001, 16, 1 ) RETURN @@ERROR この部分は通らないということですよね? よくわかりました。ありがとうございました。 では、エラー処理の仕方としては @@ERRORと@@ROWCOUNTを使用して、 処理が実際なされたかどうかの検査を行い、 ユーザーにメッセージを返すようにすれば、 sqlExceptionにスローさせることで統一できるのですね。 | ||||||||
|
投稿日時: 2005-03-31 21:01
そうですね。通っていないはずです。 う〜ん?
SQL Serverが出している問題ではないのですから、DBConcurrencyExceptionで受ければいいのでは? または、DBConcurrencyExceptionが生成される状況というのが、一考の必要があるかと。 この例外は、UPDATE、INSERT、DELETEの実行による影響を受けた行がゼロの時に生成されます。そして、同時実行制御をしている&更新対象の行が必ずあるという前提で、結果が0の時に生成されます。 ここで、この前提が、個々のケースで絶対であるか、確認する必要があります。 例えば、WHERE句の指定によって、対象の行がない場合、例外が生成されます。このケースがあり得るのか、あり得ないのか、検証する必要がないでしょうか。 条件指定をユーザが行うのならば、対象行が0になる場合があり得ます。その場合に例外として扱い、エラーメッセージを出すのが正しいとは思いません。この場合、無視するか、「対象になる行はありませんでした」という普通のメッセージを出せばいいと思います。 [ メッセージ編集済み 編集者: Jitta 編集日時 2005-03-31 21:01 ] | ||||||||
|
投稿日時: 2005-04-04 18:18
Jittaさんお返事ありがとうございました。
Jittaさんのおっしゃるとおり、 WHERE句の指定によって、対象の行がないケースがあり得るのか、あり得ないのか、よく検証してから、実装することにしました。 |
1