ORDAの楽観的ロックとの連携

Deeplからの自動翻訳

4D v17 が紹介されています。 ORDAORDAは、4D開発者に新しい可能性の世界を開く、4Dの大きな進化です。ORDAを使用する利点の1つは、レコードの ロックに関連しています。ORDAのロック機構を紹介した後、ORDAシリーズを続けることで、ORDAで楽観的ロックで効率的に作業する方法を発見することができます。

例:ORDAによる楽観的ロック

楽観的ロックの概要

楽観的ロックモードでは、レコードは 更新される前に明示的にロック されることはない。

楽観的ロックは、レコードのスタンプに 依存します。各レコードには内部スタンプがあり、レコードが データベースに 保存されるたびに自動的にインクリメントされます。エンティティをロードしてからレコードが更新された場合、save(),drop(),lock()メソッドは、スタンプが変更されたことを示す特定のステータス・コードを返します。

レコードとエンティティー

レコードとは、データベース内の物理的なレコードで、エンティティを通じてアクセスされます。エンティティは レコードの参照先です(用語集のエンティティの項を参照)。レコードはエンティティを通してロックされ、ロックが解除されます。

コード例

以下の例では、メソッドが失敗する2つのシナリオを扱います。 save()メソッドが失敗する2つのシナリオを扱います。

C_OBJECT($status;$employee)

// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith").first()
If ($employee#Null)
$employee .lastName:="Wates" // Update employee's last name
$status :=$employee.save()// Save employee
if (Not($status.success))// The save action fails
Case of
// The record has been updated in database since the entity was loaded
: ($status.status=dk status stamp has changed)
alert ("ロードしてから誰かがレコードを更新しました")
//The record is locked by another process
: ($status.status=dk status locked)
alert ("誰かがレコードをロックしました")
End case
end if
end if

ケース 1: エンティティが変更された場合

エンティティをロードした後にデータベースでレコードが更新された場合、返される$status オブジェクトは以下のようになります。

{
 "status": 2,
 "statusText": "Stamp has changed",
 "success": false
}

CASE 2: ENTITY は既にロックされている

データベース内のレコードが他のプロセスによって既にロックされている場合、返される$status オブジェクトは以下のようになります。

{	 	 
 "status": 3,	 	 
 "statusText": "Already Locked",	 	 
 "lockKind": 1,	 	 
 "lockKindText": "Locked By Record",	 	 
 "lockInfo": {	 	 
     "task_id": 5,	 	 
     "user_name": "Mary Smith",	 	 
     "user4d_id": 1,	 	 
     "host_name": "iMac27-Program6",	 	 
     "task_name": "P_10",	 	 
     "client_version": -1610541312	 	 
 },	 	 
 "success": false	 	 
}

一般的なシナリオ

メソッドに付随する save()メソッドを使用します。 ORDAは非常に便利なオプションを提供します。 dk auto merge.

dk auto mergeは、メモリにロードされたエンティティで行われた更新を、データベースのレコードで行われた更新と自動的にマージ することを試みます。しかし、他のユーザーがデータベースのレコードで更新したのと同じプロパティをロードしたエンティティで更新した場合、失敗することがあります。

したがって、 これを管理するために、2つのオプションを提供します。

1- データベースで行われたアップデートを上書きする

以下の例では save()メソッドに dk auto mergeは失敗します。

他のプロセスによってデータベースで行われた更新を上書きしたいことは確かです。

この場合、次のように管理します。

1- 保存する前に clone() メソッドを使用しています。これは、更新されたエンティティに新しい参照を作成します。後で再利用するために、エンティティのコピーを作成するのは便利です。

このとき save()メソッドが失敗した場合。

2- reload() メソッドを使用して、データベースの レコードから エンティティを再読み込みし、最新のスタンプを取得できるようにします。

3- 複製されたエンティティを使用して、更新を再適用する。

4- エンティティを再度保存し、返されたステータスをテストする。

C_OBJECT($status;$employee;$clonedEmployee)
// Get the first employee whose last name is "Smith"
$employee :=ds.Employee.query("lastName=:1"; "Smith@").first
()

If ($employee#Null)
// Update the last name
$employee .lastName:="Dunaway"
// Clone the loaded entity
$clonedEmployee :=$employee.clone()
// Save the entity with auto merge option $status :=$employee.save(dk auto merge)
// The save action fails
While (Not($status.success) ))
// The auto merge failed
If

($status.status=dk status automerge failed)
// Reload the entity. The stamp will be updated
$employee .reload()
// Reapply the update on last name $employee lastName :=$clonedEmployeelastName // Save the entity $status :=$employee.save(dk auto merge)
End if
End while
End if

2- エンティティとレコードの間の競合を手動で管理するためのユーザーインターフェイスを構築する。

ORDAは、ユーザーが自分の更新と同時に行われる他のことを選択できるようなインターフェイスを構築するのに役立つメソッドを提供しています。

これらのメソッドの概要を簡単に説明します。詳細については、ドキュメントをご覧ください。

  • touchedAttributes()メソッド: エンティティをロードまたは保存した後にアクセスされた属性を返します。
  • diff()メソッド: 2つのエンティティを比較します。

提供されたHDIでは、このようなインターフェイスを構築する方法を見ることができます。

Avatar
- プロダクトオーナー - Marie-Sophie Landrieu-Yvertは、2017年にプロダクトオーナーとして4Dプロダクトチームに参加しました。プロダクトオーナーとして、彼女はユーザーストーリー(ユーザーが期待する新機能とその使用法)を書き、それを具体的な機能仕様に変換する役割を担っています。また彼女の役割は、実装された機能が顧客のニーズを満たしているかどうかを確認することでもあります。彼女は1995年にESIGELEC Engineering Schoolを卒業し、IBMでエンジニアとしてのキャリアをスタートさせました。様々なプロジェクト(保守や新規のプロジェクト)に参加し、Cobolのデベロッパーとして働きました。その後、UMLデザイナーおよびJavaデベロッパーとして勤務。最近は、機能要件の分析・記述、ビジネスチームと開発チームの調整などを主に担当しています。