Ognacの雑感

木漏れ日々

目次

Blog 利用状況

書庫

ギャラリ

RDBの制約を期待するのを良しとするか?

以前、例外を期待するソースは行儀が悪いと書いたのですが、私的にはRDBの制約違反を期待するソースも行儀が悪いと思うのです。
顧客マスターなどのマスター類の主キーはユニークです。(例外もありますが...無視)
 Code   名前
 010    Ognac
 020    Wankuma
のデータがあるとき
 020    ABC        をInsertすると重複違反例外が起こります。例外を受けて、重複メッセージを出したりしているのを見ると、いいのかなぁと思う。
これは、一度 CODE=020 の存在Checkをして、更新処理か追加処理かの分岐をすべきだと考えます。
 業務ロジックからみてもこの方が筋が通っています。例外の結果でエラーしたり更新に分岐するのは不合理です。
外部キー違反も例外を期待するのでなく、事前チェックすべきだと考えています。
RDBの制約違反はコトスが高い処理ですし、例外を期待するコーディングはロジックを考え尽くしているとは思えないのです。
 勿論反論はあります。「RDBの機能として制約が存在しており、データ矛盾を指摘する機能なので積極的に機能を利用すべきだ」と指摘されたりします。
確かに機能を利用するとコーディング量が減り見通しもよくなるような錯覚をします。
 そうでしょうか、例外を期待してのコーディングは楽なのですが、ロジック考察力が劣化するし、ソースの品質も劣化しているように見えます。
RDBの制約は、子データが存在するのに、親データを消したときの例外発生などのデータ矛盾の防止に用いるのが本筋です。
 市販本のサンプルやTips集はポイントレッスンなので局所的に正解ですが、そのままコーディング標準などに取り入れるとスキル低下をもたらす遠因になります。
サンプルを理解しないでコピペで使うプログラマが悪いのか指導者が悪いのか....個人のモチベーションなのかなぁ..向き不向きなのかなぁ...よくわからん<--ナゲヤリな俺。

-追-   一部内容が一方的な見方で間違ってました。お詫びします。コメント参照してください。

投稿日時 : 2007年8月1日 23:26

Feedback

# re: RDBの制約を期待するのを良しとするか? 2007/08/01 23:36 中博俊

>これは、一度 CODE=020 の存在Checkをして、更新処理か追加処理かの分岐をすべきだと考えます。

いいえ。
その考えは誤りです。

20の存在チェックをして存在しなくても、INSERTのタイミングでは存在する恐れがあります。

# re: RDBの制約を期待するのを良しとするか? 2007/08/01 23:39 凪瀬

私は信頼できる方法論であるのなら、採用は合理的と思います。
存在をチェックしてからUPDATEするとなると、トランザクションが長くなるわけで、場合によっては性能が落ちる可能性もあるんじゃないかな?
なお、私の専門のJavaの話で言うとJavaSE6.0より前ではJDBCの制約上、SQLでの例外の区分けがしにくいので信頼性の理由で採用したく無かったりはします。

# re: RDBの制約を期待するのを良しとするか? 2007/08/01 23:54 Ognac

え!
トランザクション内で、ストアードプロシージャ処理でも間違っている?
って、本文にそんなこと書いてない...orz.
クライアント側では確かに、存在チェックしても排他や他タスクの外部要因の関係で挿入例外は起こり得ますね。
といって例外に全面期待するのは疑問が残るのです。
>>>これは、一度 CODE=020 の存在Checkをして、更新処理か追加処理かの分岐をすべきだと考えます。
一旦自前でチェックした上で挿入処理を実行して、外部要因による例外に対応する....というのは間違い?

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 0:05 かつのり

よくやるのが、
1.select for update
2.行なしならinsert、タイミングの問題で失敗したらエラー
3.行ありならupdate
4.コミット
って感じすかね。

2の処理で失敗してから更新のような分岐は行いません。

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 0:52 Ognac

うーん! 早とちりして、エントリーしてしまった。謝罪します。<-- 最近謝罪が多いぞ。コラ
かつのりさんロジックが常道で適正ですね。しかし For Update 等の行ロックを使う悲観的ロックは、ADO.NETの思想(非接続型:楽観的ロック)と反しちゃいますね。
といって、Insertの種類ごとにストアードを書くのも不合理だし....orz.
ということは、RDBの例外を前提としてコーディングするほうがトータルコストが低いのか。奥が深い。
否定したことを訂正します。
>私は信頼できる方法論であるのなら、採用は合理的と思います。
"信頼できる方法論"という箇所も意味深ですね。

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 1:35 中博俊

ストアド内であろうとなかろうと、トランザクションないであろうとなかろうと、INSERTは競合します。
FOR UPDATE or with(UPDLOCK)できるのはレコードがある場合だけです。
別にロックテーブルなどの採用なら話は別。

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 9:23 Mr.T

Mr.Tです、こんにちは。

>ストアド内であろうとなかろうと、トランザクションないであろうとなかろうと、INSERTは競合します。

私もこっそりストアド+トラン内ではInsert競合しないと思ってました。

となると、
1)存在Checkは、ユーザに同一コードが存在するよメッセージを、見せる必要があるかどうかの判断にしかつながらない。競合をさけられるわけじゃない。

2)Insert処理ではストアド+TRANでも競合する可能性アリ。そうならない仕組みが別途あるなら競合しない。

とすれば、Insertで競合したら、もう一度ユーザにボタンを押させろ、ってことでしょうか?

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 11:51 中博俊

結局はノウハウなわけだけど(^^;
今回の場合PKを手打ちさせているわけで、競合は避けられない。
serializableなんかにすればOK
(愚策)
ロックテーブルを用いて、select * from locktable with (updlock) where tablename='顧客テーブル'
存在チェック
ってやれば確実に判断はできます。
顧客テーブル自体へのselectはロックされませんので、良いかもしれません。
例外を取る方法も万全ではなくdeleteされるおそれのあるテーブルでは
insert
失敗
updateしなきゃね
裏でdelete
update
失敗
となります。

updateの楽観ロックをどうするかもあわせると、insert 失敗画面に戻す。やり直させる。
がベターですが、画面の作りや、もろもろによって判断していく必要があります。
奥が深いですね。


# re: RDBの制約を期待するのを良しとするか? 2007/08/02 12:22 片桐

つか、そもそも論ですみませんなのですけれども、PK採番のタイミングというかやり方がヘンというか問題なくない?
UPDATEとかINSERTとかする以前に、重なりうるPKを発行する仕組み自身に???なのは私だけ……?

PK採番専用テーブルでPK発行する
インクリメント属性(ID属性)列をPKとする
データーベース処理日付時間秒(オラクルは秒、SQL-Serverならミリ秒)で処理時に採番

とかとかとか……PKにコードとかでユーザーが好きに設定できるとかなら、それはPKにはしないで、せめて何かと組み合わせてUNIQUEキーにするくらいなんではないのかなぁなんて思ってみたり

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 13:21 Mr.T

Mr.Tです、こんにちは。

あー、PK=業務で利用するユーザ側のコード
というのは、実際ままあります。
これは、
「PKは一意」
「じゃあ、ユーザが見て判断できるね」
「じゃあ、手打ちでもOK」
なんですね。

非常に楽観的ロックが期待されるところです。状況が、2~3台くらいのクライアントしかないとか、
マスタはめったにさわらねーとか、マスタ触れる権限があったりするとか、
楽観的ロックに追い風となるケースですね。

私は、他のデータとの整合性がとれるなら、手打ちでもいいよーとします。

ま、明細とかはサロゲート利用するとかあるけど、マスタはPK手打ちでもいいかなぁって思います。

マスタはデータの反映に即効性が求められてないから、競合したので、もいっかい押してね、でええんじゃないかなと。

# re: RDBの制約を期待するのを良しとするか? 2007/08/02 23:04 Ognac

皆様ありがとうございます。奥が深いですね思慮不測でした。
トランザクション云々のレベルとは無関係の所で同じPKで挿入されるのは普通であり得ますね。
となるとInsert時の例外は避けられないですね。「例外を期待するのは?」の場面でInsert例外を出した時点でダメで浅はかでした。

# バーバリー マフラー 2012/11/06 15:18 http://www.burberryfactory.com/バーバリー-マフラー-c-4.html

こんにちは、またブログ覗かせていただきました。また、遊びに来ま~す。よろしくお願いします

タイトル
名前
Url
コメント