データの削除には注意が必要です。問題を防ぐために、トランザクションを使用したり、バックアップやログに頼ったりすることができます。
4D 20 R4 では、セレクション内のレコードを削除した場合に一貫性を保ち、セレクションを安定させるために、いくつかの改善がなされました。
重要: これは、4D標準のQUERYコマンド と ORDA で扱われるデータの両方に適用されます。
どのようにあなたの4Dコードが安全なものになるのか、続きをぜひご一読ください。
4D内部の動作
すでにご存知かもしれませんが、4D は内部的に、ディスク上の物理的なデータブロックを指すアドレステーブルを使用しています。4D の内部アーキテクチャーにおけるこのアドレステーブルの扱いによって、思わぬ結果につながることがあります。
レコードが削除されると、その物理データへの参照はアドレステーブルから削除されます。
アドレステーブルのメモリ使用を最適化するため、新しいレコードが作成されると、4Dはアドレステーブルの空き領域を再利用します。
クエリなどによりレコードのセレクションを構築した後、このセレクションに属するレコードが別ユーザーにより削除され、新しいレコードが作成された場合、アドレステーブルの以前とレコード番号を通してその新しいレコードが参照されてしまう可能性があります。
このように過去には、まったく予期しないデータがセレクションに含まれていることがありました。
具体例
ある従業員がタスクのスタックを抱えているとします。タスクを新規作成すると、そのタスクのステータスは TO DO になります。
残っている TO DO タスクは、定期的に従業員にメール送信されます。それらのタスクのセレクションが作成され、ループにより各タスクを走査して、タスクの詳細がメールに記載されるようにします。
さて、ここでタスクを削除する権限を持っている管理者もいます。もし、管理者が上記のセレクションに含まれているタスクを誤って削除してしまい、その直後に別の社員の新規タスクが作成されたとしたら…どうなるでしょうか?
4D 20 R4 以前
新しく作成されたタスクはループ内で見つかって処理されますが、別の従業員のタスクなので、完全に範囲外です!
4D 20 R4 以降
新しく作成されたタスクはループ内で見つからず、データのセレクションは常に一貫しているため、安心して使うことができます。
ほとんどの場合、レコードの削除は実際にデータを消去するのではなく、ステータスの変更で対応するため、このユースケースが現実で起こることは少ないかもしれません。
あるいは、特定のレコードやエンティティが選択条件に合致することを再確認してから処理を進めることもあるでしょう。
いずれにせよ、今後はもう気にする必要はありません。
実際にコードで見てみましょう
以下の例では、$target エンティティセレクションを作成しています。
この後、このエンティティセレクションに属しているエンティティを削除します (理解しやすいように同じコードでおこなっていますが、これは別ユーザが別プロセスでおこなうことを想像してください)。
ループは、残った 2つのエンティティ (internalID 10 と 12) だけを処理します。
var $target; $customers : cs.CustomersSelection
var $customer : cs.CustomersEntity
var $newCustomer : cs.CustomersEntity
var $status : Object
// internal ID が 10, 11, 12 に合致する 3件のエンティティを取得します
$target:=ds.Customers.query("internalID >= 10 and internalID <= 12")
ASSERT($target.length=3)
// internalID = 11 のエンティティを削除します
$customers:=ds.Customers.query("internalID = :1"; 11).drop()
// internalID = 99 のエンティティを新規作成します
$newCustomer:=ds.Customers.new()
$newCustomer.internalID:=99
$status:=$newCustomer.save()
// 新規エンティティの作成前に取得した
// $target エンティティセレクションをループします
For each ($customer; $target)
// 新規エンティティはエンティティセレクションに存在しません
ASSERT($customer.internalID#99)
End for each
冒頭でも触れましたが、これは 4D標準のQUERYコマンド と ORDA で扱われるデータの両方に適用されます。
様々な心配事の解決は 4D に任せて、ビジネスロジックに集中し、安心して 4D をお使いください!