記事
· 2023年2月27日 7m read

Ensembleでの孤立メッセージ

今回は、「孤立メッセージ」について説明します。

孤立メッセージとは何ですか?

すべてのメッセージボディは、メタデータを保持するメッセージヘッダと関連付けらます。ヘッダーには、ソース構成名称、ターゲット構成名称、作成時刻、処理時刻、関連するメッセージボディ参照、セッション情報、メッセージボディのクラス名称、メッセージステータスなどの情報が格納されます。 メッセージボディに対応するヘッダーレコードが存在しない場合、そのメッセージボディは孤立メッセージボディと呼ばれます。ここでは、孤立メッセージボディの原因となる可能性があるものについて説明します。

ヘッダーのみを削除する場合

削除タスクの設定において、BodiesToo メッセージヘッダとともにメッセージボディも削除するかどうかを指定するものです。この設定をOFFにすると、削除タスクはメッセージヘッダーのみを削除し、メッセージボディは残します。これらのメッセージボディは、参照されたヘッダが削除されることから、孤立したレコードとなります。 メッセージヘッダの削除したが、メッセージボディは残している場合、マネジメントポータルでは孤立メッ セージボディを削除する方法はありません。この場合、プログラムによってメッセージボディを削除する必要があります。

 

削除タスクについては、ドキュメントをご参照ください。

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EGMG_purge#EGMG_purge_basic

複合メッセージボディの クラス (オブジェクトの値によるプロパティ)

Ensemble がメッセージボディを削除する際、メッセージボディのオブジェクトの値によるプロパティが削除されるとは限り ません。具体的には、他のオブジェクトを削除するのは、それらがシリアルオブジェクトであるか、子オブジェクト(関係によって定義される)である場合のみである。その他のオブジェクトについては、削除トリガーを定義するか、メッセージボディのクラスで %OnDelete() 方法を実装して、適切に削除を処理する必要があります。

OnDelete実装のサンプルコード

Class Sample.Address Extends %Persistent{
/// 所番地。
Property Street As %String(MAXLEN = 80);
/// 市名。
Property City As %String(MAXLEN = 80);
/// 2文字の州の略称。
Property State As %String(MAXLEN = 2);
/// 米国の5桁のZIP(Zone Improvement Plan)コード。
Property Zip As %String(MAXLEN = 5);
}
Class Sample.Person Extends %Persistent{
/// 本人の名前。
Property Name As %String [ Required ];
/// 本人の社会保障番号。これはパターンマッチで検証さ れます。
Property SSN As %String(PATTERN = "3N1""-""2N1""-""4N") [ Required ];
/// 本人の生年月日。
Property DOB As %Date;
/// 本人の自宅住所。
Property Home As Address;
/// 本人の勤務先住所。
Property Office As Address;
///オブジェクトを削除するためのコールバック。
ClassMethod %OnDelete(oid As %ObjectIdentity) As %Status [ Private ]{
      // プロパティオブジェクトの参照を削除することです。
      Set tSC = $$$OK, tThis = ##class(Sample.Person).%Open(oid)
      If $ISOBJECT(tThis.Home) Set tSC = ##class(Sample.Address).%DeleteId(tThis.Home.%Id())
      If $ISOBJECT(tThis.Office) Set tSC = ##class(Sample.Address).%DeleteId(tThis.Office.%Id())
      Quit tSC
}
///SQL削除のコールバック/トリガー
Trigger OnDelete [ Event = DELETE ]{
      // プロパティ・オブジェクトの参照を削除します。{%%ID} は削除されるレコードの ID を保持します。
      Set tID={%%ID}
      Set tThis = ##class(Sample.Person).%OpenId(tID)
      If $ISOBJECT(tThis.Home) Do ##class(Sample.Address).%DeleteId(tThis.Home.%Id())
      If $ISOBJECT(tThis.Office) Do ##class(Sample.Address).%DeleteId(tThis.Office.%Id())
      Quit
}
}

メッセージオブジェクトが作成さられましたが、他のホストに送信されませんでした。

メッセージが別のホストに送信/転送さ れようとしたら、Ensemble は新しいメッセージヘッダを作成し、対応するメッセージボディを関連付けます。 ビジネスサービス/プロセスで作成されたメッセージボディ/オブジェクトのインスタンスがディスク/データベースに保存され、かつプロダクション内の別のホストに送信されなかった場合、関連するヘッダーがなく、孤立メッセージボディとして残ります。ベストプラクティスは、転送されない限りメッセージボディを作成しないこと、またはオブジェクトのインスタンスの %Save() をコールしないことです (SendRequestSync/SendRequestAsync API は、メッセージをターゲット設定キューに入れる前にそれを保存します)。この方法では、メッセージボディのオブジェクトは、他のホストに送信されない限り、永続化されることはありません。

この問題の最も一般的な原因は、開発者が:

  1. メッセージボディを複製し、複製されたメッセージボディを転送しない場合です。
  2. コンテキスト変数(BPL)で作成されたメッセージボディオブジェクトが転送されない場合です。

孤立メッセージの効果

孤立メッセージは、削除タスクによって削除されません。これらのメッセージはディスクスペースを消費し、その数が増えるにつれて、ディスク使用量も増加します。ディスク使用量は、メッセージボディのデータだけでなく、これらの孤立メッセージボディレコードのインデックス/サーチテーブルのエントリも含めて使用されることになります。

孤立したメッセージの特定

孤立したメッセージの存在は、メッセージヘッダとボディを照会することで 特定することができます。各メッセージヘッダは、対応するメッセージボディを参照します。メッセージボディのオブジェクトIdの参照はヘッダのMessageBodyIdプロパティに、メッセージボディのクラス名はヘッダのMessageBodyClassNameプロパティに格納されます。

HL7 メッセージ・テーブルで孤立メッセージを見つけるためのクエリの例:

SELECT HL7.Id  FROM EnsLib_HL7.Message HL7

   LEFT JOIN Ens.MessageHeader hdr

   ON HL7.Id=hdr.MessageBodyId

   WHERE hdr.MessageBodyId IS NULL

上記のクエリは、対応するヘッダを持たないすべての HL7 メッセージを返します。このクエリは、メッセージボディのテーブル名称を置き換えるだけで、他のメッセージタイプに対するクエリに変更することができます。

孤立メッセージの削除

マネジメントポータルでは孤立メッ セージボディを削除する方法はありません。この場合、プログラムによってメッセージボディを削除する必要があります。ENSDEMO データベースでは、Demo.Util.CleanupSet というクラスが、これを実行する方法の例を示してくれます。このルーチンは、オブジェクトのプロパティ参照も含めて深く削除します。

孤立メッセージを削除するためのルーチンがもう一つありますが、このルーチンは深い削除はしませんし、メッセージボディの削除だけを助けます。ソースをダウンロードするために、以下にgithubへのリンクを載せておきます。

https://gist.github.com/suriyasv/2ed7f2dbcfd8c79f3b9938762c17c0b5

ベストプラクティスは、

  1. 孤立メッセージを防ぐために、常にプログラミングエラーを避けることです(前述)。
  2. BodiesToo設定をOFFにした削除タスクを、ボディが必要な場合のみ設定し、これらのメッセージボディはプログラムによってのみ削除できることを認識することです。
  3. 永続オブジェクトプロパティに対するRelationshipsまたはOnDelete実装することです。

この記事が、プロダクションを構築する際にお役に立てば幸いです。また、ご不明な点などございましたら、お知らせください。ありがとうございました。

ディスカッション (0)2
続けるにはログインするか新規登録を行ってください