DBミラーリングシステムの運用を行う場合、以下の条件を満たすUPDATE文:探索を実行することができません。実行した場合、DBミラーリングシステムの制約により業務アプリケーションがエラーとなることがあります。
[条件]
設定句の列名に、一意性制約の構成列を指定している。かつ、
更新の結果、一意性制約を指定した列の値が、一時的に同じ値になる行が存在する。
[制約により出力されるエラー]
SQLSTATE | SQLMSG | メッセージログファイル |
---|---|---|
71400 | JYP2906E: DBミラーリングサービスでサポートされていない機能が利用されました. | rdb: ERROR: qdg20756u: DBミラーリングサービスでサポートされていない機能が利用されました 原因コード=3 ロググループ名='ロググループ名' RLP名='RLP名' |
エラーとなる場合の例、および対処方法について以下に説明します。
制約により業務アプリケーションがエラーとなる例
一意性制約の構成列C1の値が1,2,3 の3行について、C1を2,3,4 と更新しようとした場合に、C1=1の更新処理中に、2,2,3 と一時的に同じ値を持つキーが存在します。
備考) 更新前のC1を3,2,1の順序で処理を行った場合には、4,2,1→4,3,1→4,3,2となって条件外となります(行の並びは、実表データの格納順序や探索条件に依存します)。
対処方法
DBミラーリングシステムの制約により業務アプリケーションがエラーとならないように更新処理を変更してください。
例えば、以下のいずれかのような処理に変更すると、一時的に同じ値にならずに更新できます。
UPDATE文:位置付けでカーソルによって位置づけられた1行を更新する方式に変更
UPDATE文:探索で1行を更新するように、WHERE句に一意性制約の全構成列を指定
一時的に同じ値になることを回避する例について、以下に説明します。
レコードを更新する順序を変更することで、一意性制約の列の値が重複しないようにします。
UPDATE文:位置付けにより一意性制約を構成する列を降順に並び替え、位置づけられた1行を更新する方法に変更する場合
EXEC SQL DECLARE CR1 CURSOR FOR SELECT C1 FROM S01.T01 WHERE C2 = 100 ORDER BY C1 DESC FOR UPDATE; EXEC SQL WHENEVER NOT FOUND GOTO :CLOSE_01; EXEC SQL OPEN CR1; for (;;) { EXEC SQL FETCH CR1 INTO :H01; EXEC SQL UPDATE S01.T01 SET C1 = C1 + 1 WHERE CURRENT OF CR1; } CLOSE_01: EXEC SQL CLOSE CR1; EXEC SQL COMMIT WORK;
UPDATE文:探索で1行を更新するように、WHERE句に一意性制約の全構成列を指定する場合
EXEC SQL SELECT MAX(C1) INTO :max_data FROM S01.T01 WHERE C2 = 100; for (count=max_data; count!=0; count--) { EXEC SQL UPDATE S01.T01 SET C1 = C1 + 1 WHERE C1 = :count AND C2 = 100; } EXEC SQL COMMIT WORK;