SQL Server、Oracle Database、およびMySQLの場合、レコードの更新時に楽観的同時実行制御(楽観的ロック)を行うようにすることが可能です。ODBCデータソースでは、同時実行制御はサポートされていません。
この同時実行制御が行われるのは以下の場合のみとなり、それ以外の場合には同時実行制御は行われません。
[更新対象レコード]が「カレントレコード」に設定されている[テーブルデータの更新]コマンドを使用して更新を行ったとき
[編集を許可]オプションが有効で、かつ[リストビューのデータを即時更新しない]オプションが無効であるリストビューで、ユーザーがカレントレコードを変更することで編集したレコードの更新を行ったとき
ワークフローバー型セルのボタンを使用して、ユーザーがワークフローを次の状態に進める操作を行ったとき
[処理の種類]が「リストビューの更新確定」に設定されている[リストビューデータの更新]コマンドを使用して更新を行ったとき
上記の場合において同時実行制御が働いた場合、以下のようなメッセージが表示され、更新処理はキャンセルされます。
更新対象のテーブルにrowversionデータ型の列が含まれている場合、Forguncyはその列を使用して同時実行制御を行います。
同時実行制御を有効化するためには、いくつかの条件と設定が必要です。
以下のようなトリガーを作成し、更新対象のテーブルに最終の更新日時が格納されるTIMESTAMP型の列を用意します。なお、Oracle DatabaseのTIMESTAMP型は既定では秒の小数部は6桁となりますが、任意の桁数を指定可能です。必要に応じてより高い精度の桁数を指定してください。
作成するトリガーの一例 |
コードのコピー |
---|---|
CREATE OR REPLACE TRIGGER trigger_testRowversion BEFORE UPDATE ON TABLE1 FOR EACH ROW BEGIN :new."rowversion" := current_timestamp; END trigger_testRowversion; |
作成した列(上記の場合「ROWVERSION」)を[行のバージョン管理フィールド]として設定します。このように設定することで、Forguncyはその列を使用して同時実行制御を行います。
Forguncyは更新対象のテーブルで最初に見つかったtimestamp型の列を使用して同時実行制御を行います。その際、レコードの値が変更された際にタイムスタンプが自動更新されるようにON UPDATE CURRENT_TIMESTAMP句が使用されている必要があることに注意してください。また、timestamp型の定義がtimestamp(6)などのようにミリ秒やマイクロ秒といた精度の値が保持されるようになっていない場合、精度の高い同時実行制御は行われません。
同時実行制御は行われません。以下の方法を用いて、手動で同時実行制御を実装することを検討してください。なお、この手動による同時実行制御は「テーブルデータの更新」コマンドを使用してレコードの更新を行う場合にのみ有効です。リストビューの[編集を許可]オプションを使用してレコードの更新を行う場合には、同時実行制御は行われませんので、注意してください。
同時実行制御を行いたいテーブルに任意の名称の文字データ型の列を1つ追加します。格納するデータは36桁の英数字(ハイフン含む)となりますので、このデータが格納できるサイズで作成してください。ここでは列名を「行バージョン」とします。
レコードの更新を行うページの任意のセルに、「行バージョン」とデータ連結を設定します。通常、この「行バージョン」のデータはページに表示する必要がないため、列の非表示か行の非表示の機能を使用して、表示されないように設定します。
レコードの更新を行う部分で、「条件分岐」コマンドを1つ追加し、以下のような条件を設定します。
3の条件が合致した場合に実行するコマンドとして、以下のような設定の「テーブルデータの更新」コマンドを設定します。「%GUID%」キーワードは、GUIDを返すForguncyが持つ特別なキーワードです。GUIDは128ビットの整数値からなる、データを一意に識別するために用いられる識別子です。
3の条件が合致しなかった場合に実行するコマンドとして、以下のような設定の「メッセージの表示」コマンドを設定します。メッセージ内容は任意のもので構いません。