ここは旧式の4DドキュメントWebサイトです。最新のアップデートされたドキュメントを読むには新サイトをご利用下さい→ developer.4d.com

ホーム

 
4D v19
エンティティロッキング

エンティティロッキング  


 

 

一般的に、複数のユーザーあるいはプロセスが同じエンティティを同時に読み込んで変更しようとした際に発生する可能性のある問題を管理する必要があります。レコードロックは、リレーショナルデータベースにおいてデータに矛盾した更新がなされないようにするために使用される手段です。読み込み時にレコードをロックして他のプロセスが更新できないようにする、あるいは逆に保存時に読み込んでからの間に他のプロセスがレコードを変更していないかどうかを検証する、というのが基本的な概念です。前者はペシミスティック・レコードロックと呼ばれ、他のユーザーからレコードをロックすることで、変更したレコードを書き込むことができるようにするものです。後者はオプティミスティック・レコードロックと呼ばれ、レコードが更新される必要がある場合にのみ書き込み権限を与えるという柔軟性があります。ペシミスティック・レコードロックでは、レコードは更新される必要がないときでもロックされたままです。オプティミスティック・レコードロックではレコードの書き込みの可能/不可能は更新時に判断されます。

ORDA では、以下の二つのロックモードを提供しています:

  • 自動的な"オプティミスティック"モード。多くのアプリケーションに適しています。
  • "ペシミスティック"モード。エンティティをアクセスする前にロックします。

この自動機構は、"オプティミスティック・ロック"に基づいたもので、これはWeb アプリケーションの場合において特に適しています。この概念は以下のような動作原理に基づいています:

  • 全てのエンティティは必ず読み書き可能な状態でロードされます。エンティティの事前ロックというのはありません。
  • 各エンティティには保存されるたびにインクリメントされる内部的なロックスタンプを持っています。
  • プロセスあるいはユーザーがentity.save( ) メソッドを使用してエンティティを保存しようとした場合、4D は保存しようとしているエンティティのスタンプの値とデータ内にあるエンティティのスタンプの値を比較します(データ編集の場合):
    • 値が合致している場合、エンティティは保存され、内部スタンプの値はインクリメントされます。
    • 値が合致しない場合、読み込みからの間に他のユーザーがエンティティを編集したことになります。保存は実行されず、エラーが返されます。

オプティミスティック・ロックの動作は以下ように図解することができます:

1. 二つのプロセスが同じエンティティを読み込んだとします。

2. 最初のプロセスがエンティティを編集し、それを保存しようとします。するとentity.save( ) メソッドが呼び出されます。4D エンジンは、編集されたエンティティの内部スタンプ値とデータに保存されているエンティティの内部スタンプ値を自動的に比較します。これは合致しますので、エンティティは保存され、その内部スタンプ値はインクリメントされます。

3. 二つ目のプロセスが読み込んだエンティティを編集し、それを保存しようとします。entity.save( ) メソッドが呼び出されます。編集されたエンティティの内部スタンプ値はデータに保存されているエンティティの内部スタンプ値と合致しないので、保存は実行されず、エラーが返されます。

この流れは以下のコードのように分解することもできます:

 $person1:=ds.Person.get(1) //エンティティを参照
 $person2:=ds.Person.get(1) //同じエンティティを他からも参照
 $person1.name:="Bill"
 $result:=$person1.save() //$result.success=true, 変更は保存される
 $person2.name:="William"
 $result:=$person2.save() //$result.success=false, 変更は保存されない

この例では、$person1 にPerson の、キー1のエンティティを代入します。次に、同じエンティティの他の参照を変数$person2 に代入します。$person1 を用いて、人物の名前を変更してエンティティを保存します。同じことを$person2 を使用して実行しようとすると、4D はディスク上のエンティティをチェックし、変数$person1 に代入されたときのものと同じかどうかを調べます。結果としてこれは同じものでは無いので、success プロパティにはfalse が返され、二つ目の変更は保存されません。

こういった状況が発生した場合、例えばentity.reload( ) メソッドを使用してディスクからエンティティを再読込し、変更をもう一度行うことができます。またentity.save( ) メソッドでは、プロセスが変更した属性が同じでなかった場合には保存を実行する"automerge"オプションも提供しています。

注: レコードのスタンプは、トランザクションでは使用されません。このコンテキストではレコードのコピーは一しか存在しないからです。レコードを参照しているエンティティがいくつあろうと、同じコピーが編集されることになるので、entity.save( ) オペレーションはスタンプエラーを生成することはありません。

エンティティは、必要に応じてデータアクセス時にエンティティをロック・アンロックすることができます。エンティティがプロセスからロックされている場合、そのエンティティはプロセスに読み書き可能モードで読み込まれていますが、他の全てのプロセスからはロックされています。エンティティは他のプロセスからは読み込みモードでのみ読み込むことができます。つまりその値は編集したり保存したりすることができません。

この機能はEntity クラスの2つのメソッドに基づいています:

詳細な情報については、これらのメソッドの説明を参照してください。

クラシックコマンドとORDA コマンドの両方を使用してレコードをロックする場合、以下の原則に注意する必要があります:

  • クラシック4D コマンドを使用してレコードをロックした場合、そのレコードに合致するエンティティをORDA でロックすることはできません。
  • ORDA を使用してエンティティをロックした場合、そのエンティティに合致するレコードをクラシック4D コマンドでロックすることはできません。

これらの原理は以下のような図に表すことができます:

トランザクションロックはクラシックコマンドにもORDA コマンドにも両方に適用されます。マルチプロセスあるいはマルチユーザーアプリケーションにおいては、トランザクション内でクラシックコマンドを使用してレコードをロックした場合、そのトランザクションがOKされるかキャンセルされるまで、他のプロセスからそのレコードにリレーとされたエンティティをロックすることはできません(逆もまた然りです)。

  • クラシックコマンドを使用してロックした場合:
  • ORDA メソッドを使用してロックした場合:



参照 

エンティティ

 
プロパティ 

プロダクト: 4D
テーマ: ORDA

 
ページの目次 
 
履歴 

初出: 4D v17

 
ARTICLE USAGE

デザインリファレンス ( 4D v19)