top / index / prev / next / target / source
日記形式でつづる いがぴょんコラム ウェブページです。
今日は書籍執筆。でも明日から東京出張です。超忙しいです。
今携わっている仕事で J2EE PetStoreのソースファイルに SELECT FOR UPDATEに関する腐った記載がありました。ドキュメントには変更のための各種記載があるようなのですが、そもそも 最大公約的なデータベースで動作するソースファイルであって欲しいものです。で、これに対応するための変更をメモっ。
そして PetStoreには関わらず、SELECT なにがし FOR UPDATEをJDBCで利用するための方法はメモの価値が大いにあります。
Microsoft SQL Server 2000では SQL文に FOR UPDATE は利用できません。※2005.05.20追記 SQL Serverの場合には WITH句を利用することが判明。詳しくは 関連する日記の箇所に詳細な記載があります。
Oracle 9i, PostgreSQL 8.0の場合には、SQL文に FOR UPDATEを明記する必要があります。
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery("SELECT 項目1, … FROM 表名 DB固有の更新ロック構文");
if (rs.next()) {
rs.updateInt("項目1", 値);
rs.updateRow();
}
※2004.03.13 トランザクション遮断レベルというものを設定しないと、期待のトランザクション遮断レベルで実行されません。※2005.05.20 なお、トランザクション遮断レベルは、デフォルトでリードコミット (TRANSACTION_READ_COMMITTED) である場合が多いです。リードコミットであれば、リードコミットという挙動の範囲で適切な行ロックが確保できます) ただ、上記ソースコードは コンパイルができない単なるサンプルなので、動作するかどうかについては別の資料 (例えば blancoDbチュートリアル)などを参照ください。
2003.10.14 山本さんの指摘を反映
2004.03.05 artonさんのツッコミにより、wildcatsさんのツッコミに気が付きました。Oracle 9i は 少なくとも SQL文に FOR UPDATEを加える必要があることを、ここで初めて知りました。…中略…
2005.05.20追記 blancoDbに携わっているうちに、FOR UPDATEは かなり把握することができました。最大公約数的な現状および結論としては下記のようになります。
リレーショナルデータベース固有の設定を行います
SQL Server 2000の場合には、接続文字列に特定の文字列 (SelectMethod=cursor) を加える必要があります。
トランザクション遮断レベルについては、何がデフォルトになっているのかについては確認をするようにしてください。なお、多くのJDBCドライバでは、リードコミットをデフォルトとしている場合が多いです。リードコミットのレベルによるロックで良い場合には、デフォルトのまま利用するのを無難と私は考えています。
自動コミットを off に設定します。 例 Connection.setAutoCommit(false) 参考: setAutoCommit(false)を忘れると結果セットが不思議な動きをしてしまいます。 参考: トランザクション分離レベルについては、デフォルトの値である Connection.TRANSACTION_READ_COMMITTED を採用しました。ケースバイケースだとは思いますが、速度との兼ね合いや「安定度」などを考慮する必要があるでしょうね。
リレーショナルデータベース固有の 更新ロックに関する構文を追加します。
Oracle 9i , PostgreSQL 8.0 : FOR UPDATE
Microsoft SQL Server 2000 : WITH (UPDLOCK)
※JDBC APIの記載とは裏腹に、FOR UPDATE句 や WITH句などを用いて更新カーソルである旨を明示する必要があります。
prepareStatementに対して、ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE のフラグをセットして実行します。(スクロールの方向性について、ほとんどの場合はResultSet.TYPE_SCROLL_INSENSITIVE を選択することになります。なぜなら 実行中に他のトランザクションの更新結果を結果セットに反映させたいという局面は少ないだろうからです。) prepareStatement(SQL文, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
JDBCドライバによっては、ResultSet.TYPE_FORWARD_ONLY を SENSITIVEと同じ扱いにしてしまうものがあります。要注意です。すなわち結果セットが他のトランザクションの更新結果を反映して、処理中にどんどん変化していきます。
このようなことから、じつは更新カーソルであっても無くても ResultSet.TYPE_SCROLL_INSENSITIVE の指定をしておくのが無難と考えることもできます。つまり ある時点でのスナップショットとしての結果セット(つまりカーソル)を維持しておくのが、プログラミングとして常識的な挙動を行うと考えるからです。(2005.05.24追記)
updateString などを呼び出して列を更新します。
最後に updateRow を呼び出して、行に対する更新を行います。
blancoDbが利用できる方は、自動生成される SimpleXXXXXUpdatableIterator.javaの内容をご覧くださいませ。
関連する日記
昨日から書籍執筆に復帰しました。仕事が荒れまくり。しかし明日からは東京出張シリーズです。今日中に何とか指定箇所までは脱稿せねば…。
13:37 スランプ。なんだか執筆スキルというか魂の叫びが全く無い。文章が湧いてこない。ぐはあああああああ。(しかし明日は朝から東京に移動だもんなぁ)
16:20 ようやっと執筆エンジンが起動する。もはや完全に手遅れの感があるが、これから頑張ります。燃えてきた~。めらめら。ぱちぱち。
21:08 なぜ私はコンスタントに執筆できないのだろう、と素朴な疑問。とりあえず たった今は 超ノリノリです (苦笑)ああっ、コンスタントに仕事を遂行していく能力が私にあれば… それは決して私では無いよなぁ (爆笑)
23:08 さすがにだんだん 意識がもうろうとしてくる。これはやばい。
パソコンテレビ録画&再生&DVD作成に利用しているハードウェア・パーツを ざざっとメモっておきます。
NEC SmartVision HG2 PK-VS/AG31/S http://www.yodobashi.com/enjoy/more/i/11482956.html 通常の予約録画&視聴にはこれを利用しています。普段撮り溜めるには、ハードウェアMPEG2エンコーダ搭載は必須項目でした。また、おまかせ録画機能が大変気に入っています。私はクラシック音楽ジャンルを視聴したいのですが、SmartVisionが自動的にテレビ番組表をチェックして クラシック音楽を がんがん自動録画してくれます。ものぐさな私にはぴったりです。気になる音質なのですが、MPEG-1 Audio Layer-2 48000Hz 224kbps で保存している模様です。PCMがオプションで選択できれば満点なのですけれどもね。画質の方は 標準が CBRの4000kbpsであるようです。カスタムで選択可能なVBR+4500kbps設定よりもCBRを使った標準画質の方が画質感が安定しているように思えました。
I-O DATA GV-1394TV (\31,800.-) http://www.iodata.co.jp/products/video/2003/gv-1394tv/index.htm これは永久保存版、という作品には こちらのハードウェアでAVI保存して後、TMPGEnc Plus 2.5で時間をかけてゆっくり編集&エンコードした後 下記のペガシス社製2製品を用いてDVD化を行っています。これはDV機器として認識されます。ゴーストリデューサーや3次元信号分離など 機能満載です。こちらの系統経由だと 音質をPCMのまま デグレードせずにDVD化できますし、また画質も DVD容量一杯のレベルに VBRなりCBRなりを選択しながら 調整することができて とても満足です。ただし こちらのケースでは とっても時間がかかります。2時間作品だったら コンピュータ上での処理が 丸1日かかります。(ほんとうに!) 最近は VBRよりもCBRで その代わり 画質調整を めい一杯時間がかかる設定にしてMPEG2作成を行ったり、などという設定に興味を持っています。(VBRだと設定の調整に失敗したら 通常のDVDプレーヤーで再生できないのではないかと、最近疑っています) CBRで最高画質設定にして気合いでMPEG2エンコーディングを行うと、実際の再生時間の10倍もの時間がエンコーディングに必要になります。びっくりですね。ちなみに リニアPCM音質で2時間番組をDVD-Rに焼き付けると 映像は 3500kbps程度の割り当てになります。720x480で3500kbpsだと よっぽどMPEG2エンコーダー処理に気合いが入っていないとブロックノイズがばしばし発生してしまいますものね。
ペガシス TMPGEnc Plus 2.5 (\7,350.-) http://www.pegasys-inc.com/j_tmpgenc.html AVI -> MPEG変換で利用している。CMカットなどをここで行っている。定評のあるMPEG-2エンコーダ。
ペガシス TMPGEnc DVD Author 1.5 (\6,800.-) http://www.pegasys-inc.com/j_tmpg_author15.html DVDオーサリングソフト。DVDメニューなどをここで作成する。シンプルで かつ 使い心地が良い。DVD焼き付けまで このソフトで完結して実施できる点も嬉しい。
120GB程度のHDD 物理的に OSなどとは別のHDDに録画データを保持するのが良い模様。また、指定可能な最大クラスタサイズ(アロケーションユニットサイズ)でフォーマットして利用しています。NTFSなので64KBが最大値になります。
メルコ(BUFFALO) DVM-4242IU2 IEEE1394&USB2.0対応DVD±R/RWドライブ http://buffalo.melcoinc.co.jp/products/catalog/item/d/dvm-4242iu2/index.html ±両方対応+外付けのもので 購入当時では一番安かったです。