ロックとトランザクション: 楽観ロックの概要

Magic uniPaaS や Magic xpa の楽観(的)ロックは次のような動作になります。

更新対象となるレコードは、2回読み込みされます。
1度目は、クライアントにレコード表示するために読み込みします。
これが初期状態となります。

2度目は、 遅延トランザクションがコミット(確定)されるとき、即ち、物理的にデータベースへの書き込みが発生するときに、最新情報として読み込みします。
1度目と2度目の値が同じであれば、ロックは発生しません。
異なっていれば、ロック発生として書き込み処理は行われません。

ここで、いくつかの注意点があります。
まずは、2度目の読み込みタイミングです。
Magicの伝統的な動作は「レコード後処理を通った後に書き込み」ですが、これはリッチクライアントタスクでも同じです。
しかし、このときの書き込みは遅延トランザクションのキャッシュに対してです。
いきなりデータベースではありません。
従って、レコード後処理を通った直後に2度目の読み込みが発生するとは限りません。
2度目の読み込みは遅延トランザクションのコミット時です。

次に何を比較するか?です。
1度目と2度目の読み込みでは、必ずしもレコードの全項目を比較するわけではありません。
データリポジトリのデータソース特性によって決まります。
更新レコードの識別、という設定です。

テーブル特性

例として、顧客マスタには次の3項目があるとして考えてみましょう。
・顧客番号 ← キー(上記の「位置」になります)
・顧客名
・住所

<更新レコードの識別が「位置」の場合>
顧客番号だけを比較します。
普通は主キー項目の値を変更することはしませんので、ほとんどの場合、ロックなし状態で更新されます。
つまり、黙って上書き更新です。
俗に、「後勝ち」などと表現することもあります。
Pervasiveの場合、デフォルトでは、これになります。

<更新レコードの識別が「位置と選択項目」の場合>
タスクのデータビューで選択(セレクト)した項目全体を比較します。
上記3項目をデータビューで選択して、同じレコードをユーザAとユーザBとで更新するとします。
ユーザAは顧客名を変更しました。
ユーザBは住所を変更しようとしています。
異なる項目に対する更新ですが、データビューの項目のどれかが異なればロック発生と認識されるので、ユーザBは「やり直し」を要求されることになります。

<更新レコードの識別が「位置と更新項目」の場合>
タスクの更新(変更)された項目のみを比較します。
上記3項目をデータビューで選択して、同じレコードをユーザAとユーザBとで更新するとします。
ユーザAは顧客名を変更しました。
ユーザBは住所を変更しようとしています。
この場合、異なる項目に対する更新なので、ロック発生とは認識されません。
両ユーザとも、何事もなく正常に更新されます。
OracleやSQL Serverの場合、デフォルトは、これになります。