ORDAシリーズが続きます!今回のブログでは、ORDAの概念を用いてデータベースでロックを使用する方法について見ていきましょう!複数のユーザやプロセスが同時に同じレコードを読み込んだり、変更しようとしたときに起こるかもしれない競合を管理する必要があることはよくあることです。レコードロックは、データの一貫性のない更新を避けるために、リレーショナルデータベースで使用される方法論です。
ORDAは、すでにご存知のもの(悲観的ロック)に加えて、楽観的ロックモードを提供します。
Different locking modes
レコードとエンティティー
レコードとは、データベース内の物理的なレコードで、エンティティを通じてアクセスします。エンティティは レコードの参照先です(用語集のエンティティの項を参照)。レコードはエンティティを通してロックされ、ロック解除されます。
楽観的ロック
楽観的ロックでは、レコードを保存する前に、エンティティでロードしてから他のプロセスでレコードが変更されたかどうかを確認します。その利点は、レコードが保存メソッドの間だけロックされることです。
楽観的ロックは、レコードのスタンプに依存しています。各レコードには内部スタンプがあり、レコードがデータベースに保存されるたびに自動的にインクリメントされます。エンティティをロードしてからレコードが更新された場合、save(),drop(),lock()メソッドは、スタンプが変更されたことを示す特定のステータスコードを返します。その後、この衝突をどう処理するかを決めなければなりません。
デフォルトでは、ORDA は 楽観的ロックで 動作しますが、 悲観的ロックも 利用可能です。
例
C_OBJECT($employee;$statusSave)
// Get the first employee whose last name is "Wates"
$employee :=ds.Employee.query("lastName=:1"; "Wates").first $statusSave
()
If ($employee#Null)
// Set name to "Mac Arthur"
$employee .lastName:="Mac Arthur"
// 従業員を保存
:=$employee.save()
// Test if the save is successful If ($statusSave.success)
ALERT ("Successfully saved!")
End if
End if
// データベース内のレコードは更新されました。
楽観的ロックについてもっと知りたくなったのではないでしょうか。この概念に完全に特化した別のブログ記事を近日中にアップします。ご期待ください。
Pessimistic locking
悲観的ロック モードでは、レコードは読み込まれるときにロックされ、他のプロセスでは更新できません。これは、他のユーザーに対するレコードのロックを犠牲にして、変更されたレコードを書き込むことができることを保証します。レコードは、同時アクセスがない場合でもロックされます。
悲観的なロックでは 、レコードを 更新する前にロック し、更新後にロックを解除 する必要があります。レコードがロックされている限り、他のプロセスでのレコードの保存/ドロップ/ロックは、それをロックしたプロセスによってロックが解除されるまで失敗します。
エンティティをロックするにはlock()メソッドを、ロックを解除するにはunlock()メソッドを使用します。
古典的な “4D “は 悲観的なロックを使用します。
例
C_OBJECT($employee;$statusLock;$statusSave;$statusUnLock)
// Get the first employee whose last name is "Wates"
$employee :=ds.Employee.query("lastName=:1"; "Wates").first
()
If ($employee#Null)
$statusLock :=$employee.lock()// Lock the entity
// The entity has been successfully locked
If ($statusLock.success) $employee.lastName:="Mac Arthur"// Set name to "Mac Arthur"
// Save employee-No need to check the status because the entity is locked
$statusSave :=$employee.save()
// Unlock entity, so other processes will be able to save/drop/lock it
$statusUnLock :=$employee.unlock()
。 End if
End if
// The record in the database has been updated
ORDA は、レコードをロックしたエンティティへの参照が無くなれば、自動的にロックを解除しますので、ロック解除のし忘れを心配する必要はありません。