[Seasar-user:2604] Re: S2DAOによる行ロックについて

J.r0ck j69
2005年 9月 26日 (月) 21:37:21 JST


J.r0ckです。

土曜日からほとんど寝ておらずかなりハイになっているので
間違いがあったらごめんなさい(汗)

> NSQ@佐藤です。

> (ちなみに、S2DAOを使用してSQLファイルを準備して、FOR UPDATEを記述した
> SQLを発行した場合にはエラーとなってしまいます。Oracleの場合、「ORA-
> 01002: フェッチ順序が無効です。」 )
このエラーは、SELECT〜FOR UPDATEを実行した後、コミット、その後にその
レコードセットに対して操作を行ったために発生しているエラーかと
思われます。
詳細なロジックはわからないのですが、S2を使う上でのトランザクションの
制御など今一度見直してみてはいかがでしょうか?

> UserTable
> -----------------------------
> ID
> NAME
> UPDATE_COUNT
> -----------------------------
> 
> そこで「このテーブルに同一IDが存在しない場合はINSERT。同一IDが存在する場
> 合にはUPDATE_COUNTに1を加算する。」といった処理が行いたい場合に、
> UPDATE_COUNTが最大であるレコードをFOR UPDATEで行ロックをかけた後に
> UPDATE_COUNTを加算してUPDATEを行うという方法が考えられます。
また、このケースで行ロックをかけなければいけないこと自体にも?
必要性のない行ロックをかけようとしているようにも思えます。

もし、仮にIDが一意であるならば(主キーになっているならば)
1.INSERTする。
2.一意制約違反が発生したらUPDATEする。
だけで、Oracleであれば暗黙のうちに排他がかかるはずですよ。
# UPDATE文は排他を司り、SELECT文は一貫性を司ります。
# この辺りの詳細は、Oracleのドキュメントを参照してください。

また、ここでUPDATE_COUNTの値をSELECT文を使ってロジックが
抱えてしまう場合に排他をかけたいなと思うのでしょうが
ロジックでは、UPDATE_COUNTの値を一切保持せず
UPDATE SET UPDATE_COUNT = UPDATE_COUNT + 1 WHERE ID = xxxx
とすれば解決できるかと...。

以上


-- 
J.r0ck <[E-MAIL ADDRESS DELETED]>




Seasar-user メーリングリストの案内