ushidayの日記

主に「IBMi」のメモに・・・

トランザクション分離レベル・省略値の違い

以前は、IBM i(AS/400)上のZend Coreにデプロイしてテストやリモートデバッグをしていたのですが、最近は、Windowsのローカル環境に立てた、Zend Server for Windowsでテストやデバッグをしてから、AS/400にデプロイしています。一人チーム開発なので、人のソースとマージしたりする事もないですし、この程度の事でも、実はソースコードのバックアップの代わりにもなったりします。(※ちゃんと正規のバックアップはしていますよ。モチロン...。)

Zend Server for Windowsを使っていて、気づいた違いについてメモを残しておきます。(「今頃、遅いよ!」と言うツッコミは無しの方向で...(-_-;)ゞ)

普段AS/400をメインで使っていると、STRSQLやSQLRPGも省略のトランザクション分離レベルが「*NC(即時コミット)」です。Zend Core for i5を使っていても省略は即時コミットです。たまーに、VBやらでODBC使うときは、「*CS(コミットされていない読取)」と言うことを思い出して、ODBCドライバの設定を「*NC」にするか、ジャーナル処理を「STRJRNPF」で開始しておきます。そうしないと、追加更新時に、”ジャーナル処理されてないお。”エラーで怒られます。ちなみにADOだと意識しなくても追加更新できるので省略が「*NC」と言うことになってるのだと思います。
ODBCの省略

本題ですが、Zend Core i5からZend Server for Windowsに移しただけで、特に動作なども問題のないアプリだったので、何も考えずテストしていたら、エントリー系のレコード追加更新で何処かで見たようなメッセージで怒られました。こんな感じのメセージです。

 [IBM][CLI Driver][AS] SQL7008N REXX 変数 "TABLE NAME " に矛盾したデータが入っています。 SQLSTATE=55019 SQLCODE=-7008

「ジャーナル処理されてないよ。」というストレートなメッセージにして欲しいのですが、どうやらこのメッセージが”ジャーナル処理されてないよ”という事みたいで、DB2 ConnectのCLI接続もODBCと同様に省略が「*NC」ではなく「*CS」の様です。

  • トランザクション分離レベルの設定で考えられそうな対処方法
    1. ジャーナル処理を開始(STRJRNPF)する。
    2. DB2 Connectの「C:\Program Files\IBM\SQLLIB\db2cli.ini」で分離レベルを指定する。
    3. SQLの「SET TRANSACTION ISOLATION LEVEL NO COMMIT」で分離レベルを指定する。
    4. SQLの「WITH句」を使って「WITH NC」で分離レベルを指定する。

まず(1)の方法ですが、対処としはジャーナルを作る事も、それはそれでアリですが、通常それ程クリティカルな要件で無い場合に、ジャーナル処理はレシーバーのオモリやリソースの消費も含めて考えると、必要では無いケースもあります。方法としては「CRTJRNRCV」→「CRTJRN」→「STRJRNPF」でジャーナルを開始します。確かにジャーナルがあると、万が一の時に、ある時点に戻る事が出来るので、トラブル時には威力を発揮してくれる事は確かでしょうが...。
■STRJRNPF

次に(2)の「db2cli.ini」でオプションを追加して、データベースカタログ単位で、分離レベルの省略を設定する事が可能です。以下が設定例です。これが一番簡単で、i5とも同期が取れるので、今回はこれを採用しました。
■「db2cli.ini」

; TXNISOLATION=1|2|4|8|32(UR|CS|RS|RR|NC 省略はCS。32はDB2 for iの即時コミット。)
[カタログ名]
DBALIAS=カタログ別名
TXNISOLATION=32

テキストファイルを直接変えてもいいですし、DB2の構成アシスタントで、選択(S)メニューのCLI設定でも変更する事が出来そうです。(自分は調子悪くてDB2GUI画面は砂時計のまま動きませんでした。)

(3)と(4)は直接SQLの発行で、指定する方法ですが、(3)に関しては上手くいくかと思いきや、駄目でした。AS/400のSTRSQL等では勿論実行できますし、i5版ですとそういった解説もあるので、もしかしたらWindows版のDB2 Connectを使っているなど、実行環境による差異が幾分ありそうです。ちなみに返されたメッセージは以下の通り、

[IBM][CLI Driver][AS] SQL0525N セクション = "1" パッケージ = "SYSSH200 " 整合性トークン = X"NULLID" のバインド時にエラーが発生したため、SQL ステートメントは実行できません。 SQLSTATE=51015 SQLCODE=-525

(4)は問題なく実行されました。ちなみに「php.ini」の”ibm_db2.i5_allow_commit ”は”0(no commit)”になっていますが、(※「i5_allow_commit」は、OS/400上のZend CoreやZend Serverにしか有効でない設定だからでした。)(2)も(4)でコミットもロールバックも出来ているので、DB2 ConnectのCLI設定が優先されている模様です。(トランザクション処理を使う場合は、autocommitオプションをOFFする必要があります。)
db2_connect()関数のオプションに”i5_commit=DB2_I5_TXN_NO_COMMIT”がありますが、これを指定してもジャーナルが開始されていないと、エラーが返されました。まだ色々と試す時間が無かったので、検証しきれていませんが、今後トライしてみて、さらに実態がつかめればと思います。