대형 MRM 메시지 핸들링

입력 비트스트림이 구문 분석되고 논리적 트리가 작성되면 대개 MRM 메시지의 트리 표현이 해당 비트스트림에 비해 더 크며 일부의 경우에는 훨씬 더 큽니다. 그러한 이유는 다음과 같습니다.
  • 오브젝트를 함께 링크하는 포인터 추가
  • 유니코드로의 문자 데이터 변환. 원래 크기의 두 배가 될 수 있습니다.
  • 비트스트림에서 암시적으로 포함될 수 있는 필드 이름 포함
  • 브로커의 조작과 연관된 제어 데이터의 존재

따라서 대형 메시지 트리를 조작하는 데 많은 저장영역이 필요합니다. 반복 구조로 구성된 대형 메시지를 핸들링하는 메시지 플로우를 설계하는 경우, 브로커의 저장영역 로드를 줄이는 데 도움이 되는 특정 ESQL문을 코딩할 수 있습니다. 이러한 명령문은 메시지에 대한 임의 액세스 및 순차적 액세스를 지원하지만, 한 번에 전체 메시지에 액세스하지 않아도 되는 것으로 가정합니다.

ESQL문은 브로커가 제한된 메시지 구문 분석을 수행하도록 하고 저장영역에 한 번에 하나의 레코드를 반영하는 메시지 트리의 일부만 보존합니다. 처리 시 레코드에서 레코드로의 정보를 보유해야 하는 경우(예: 일정한 순서의 반복 항목 구조에서 총 비용 계산) ESQL 변수를 선언, 초기화 및 유지보수 하거나 메시지 트리의 다른 부분(예: LocalEnvironment)에 값을 저장할 수 있습니다.

이 기술을 사용하면 브로커가 전체 입출력 비트스트림을 보유하기 위해 필요로 했던 메모리와 하나의 레코드 트리에 필요한 메모리가 감소됩니다. 메시지에서 반복 횟수가 적어도 메모리가 절약됩니다. 브로커는 부분 구문 분석을 사용하며, 비트스트림의 해당 부분으로(부터) 메시지 트리의 지정된 부분을 구문 분석할 수 있는 기능을 사용합니다.

Compute 노드에서 이 기술을 사용하려면 다음과 같은 일반 기술을 적용하십시오.
  • 비트스트림 입력 메시지의 본문을 출력 메시지의 특수 폴더로 복사하십시오. 이렇게 하면 구문 분석되지 않은 입력 메시지에 대한 수정 가능한 사본이 작성되고 최소량의 메모리를 사용하게 됩니다.
  • 입력 메시지를 확인하지 않도록 하십시오. 그러면 메시지를 구문 분석할 필요가 없습니다.
  • 루프 및 참조 변수를 사용하여 한 번에 한 레코드씩 메시지를 통과시키십시오. 각 레코드의 경우 다음을 수행하십시오.
    • 두 번째 특수 폴더에서 해당 출력 서브트리를 빌드하도록 정상 변환을 사용하십시오.
    • ASBITSTREAM 함수를 사용하여 최종 비트스트림의 필수 위치에 해당하는 트리의 위치에 있는 BitStream 요소에 저장된 출력 서브트리의 비트스트림을 생성하십시오.
    • 조작을 완료한 경우 DELETE 문을 사용하여 현재 입력 및 출력 레코드 메시지 트리를 모두 삭제하십시오.
    • 모든 레코드의 처리를 완료한 경우 출력 비트스트림에 나타나지 않도록 특수 폴더를 분리하십시오.

메시지에 필요한 프로세스에 맞게 이들 기술을 달리할 수 있습니다. 아래의 ESQL은 하나의 구현 예로써, 중첩된 반복 구조가 포함된 메시지를 변환하기 위해 중첩된 SELECT 함수가 있는 단일 SET 문을 사용하는 큰 XML 메시지 핸들링의 ESQL 예를 재작성한 것입니다.

ESQL은 Invoice 입력 형식과 Statement 출력 형식 둘 다에 대해 메시지를 정의하기 위해 작성한 LargeMessageExanple이라고 하는 메시지 세트에 의존합니다. 여러 번 반복할 수 있는 Invoice 전역 요소가 있는 AllInvoices 메시지와 여러 번 반복할 수 있는 Statement 전역 요소가 있는 Data 메시지가 작성되었습니다.

요소 및 속성 정의에는 올바른 데이터 유형이 제공되었으므로, XML 예의 ESQL에 사용된 CAST 문은 더 이상 필요하지 않습니다. 이름이 XML1인 XML 물리적 형식이 메시지 세트에서 작성되었습니다. 이 메시지 세트에서는 두 메시지에 해당되는 XML 메시지가 MRM에 의해 구문 문석될 수 있습니다.

Statement 트리가 ASBITSTREAM 함수를 사용하여 직렬화된 경우 메시지 세트, 메시지 유형메시지 형식은 매개변수로 지정됩니다. 메시지 유형 매개변수에는 메시지에서 직렬화되는 요소까지의 경로가 포함됩니다(이 경우 Data/Statement). Statement 요소는 Data 메시지의 인접 하위 요소이기 때문입니다.

플로우의 입력 메시지는 태그 사이에 포함되는 것을 제외하고는 문서의 다른 부분에 사용되는 Invoice 메시지 예제와 같습니다.
       <AllInvoices> ....  </AllInvoices>  

출력 메시지는 큰 XML 메시지 핸들링에 있는 것과 같습니다.

CREATE COMPUTE MODULE LargeMessageExampleFlow_Compute
       CREATE FUNCTION Main() RETURNS BOOLEAN
	BEGIN
CALL CopyMessageHeaders();
    -- Create a special folder in the output message to hold the input tree
  		-- Note : SourceMessageTree is the root element of an MRM parser
  		CREATE LASTCHILD OF OutputRoot.MRM DOMAIN 'MRM' NAME 'SourceMessageTree';

    -- Copy the input message to a special folder in the output message
    -- Note : This is a root to root copy which will therefore not build trees
  		SET OutputRoot.MRM.SourceMessageTree = InputRoot.MRM;

    -- Create a special folder in the output message to hold the output tree
  		CREATE FIELD OutputRoot.MRM.TargetMessageTree;

    -- Prepare to loop through the purchased items
  		DECLARE sourceCursor REFERENCE TO OutputRoot.MRM.SourceMessageTree.Invoice;
  		DECLARE targetCursor REFERENCE TO OutputRoot.MRM.TargetMessageTree;
  		DECLARE resultCursor REFERENCE TO OutputRoot.MRM;
    DECLARE grandTotal   FLOAT     0.0e0;

    -- Create a block so that it's easy to abandon processing
    ProcessInvoice: BEGIN
        -- If there are no Invoices in the input message, there is nothing to do
          IF NOT LASTMOVE(sourceCursor) THEN
            LEAVE ProcessInvoice;
            END IF;

        -- Loop through the invoices in the source tree
        InvoiceLoop : LOOP
            -- Inspect the current invoice and create a matching Statement
            SET targetCursor.Statement =
        		THE ( 
          			SELECT
            			'Monthly'                        AS Type,
            			'Full'                           AS Style,
                        I.Customer.FirstName                         AS Customer.Name,
                        I.Customer.LastName                          AS Customer.Surname,
                        I.Customer.Title                             AS Customer.Title,
            			(SELECT 
                            FIELDVALUE(II.Title)              AS Title,
              				II.UnitPrice * 1.6 			AS Cost,
                  II.Quantity                   AS Qty
                         FROM I.Purchases.Item[] AS II 
            WHERE II.UnitPrice > 0.0 ) AS Purchases.Article[],
            			(SELECT
              				SUM( II.UnitPrice * 
                   			     II.Quantity  *
                   				 1.6                          )
                         FROM I.Purchases.Item[] AS II        )            AS Amount,
            				'Dollars'                                  AS Amount.Currency
                    FROM sourceCursor AS I
          WHERE I.Customer.LastName <> 'White'
       				 );

            -- Turn the current Statement into a bit stream
      		-- The SET parameter is set to the name of the message set 
         -- containing the MRM definition
      		-- The TYPE parameter contains the path from the from the message 
         -- to element being serialized
      		-- The FORMAT parameter contains the name of the physical format 
         -- name defined in the message   
      DECLARE StatementBitStream BLOB
        		CAST(ASBITSTREAM(targetCursor.Statement 
        			OPTIONS FolderBitStream
        			SET 'LargeMessageExample'
        			TYPE 'Data/Statement'
        			FORMAT 'XML1') AS BLOB);
                
      		-- If the SELECT produced a result (that is, it was not filtered
         -- out by the WHERE clause), process the Statement
            IF StatementBitStream IS NOT NULL THEN
                -- create a field to hold the bit stream in the result tree
        		-- The Type of the element is set to MRM.BitStream to indicate
           -- to the MRM Parser that this is a bitstream 
        CREATE LASTCHILD OF resultCursor
          			Type  MRM.BitStream
          			NAME  'Statement'
                    VALUE StatementBitStream;

                -- Add the current Statement's Amount to the grand total
        		SET grandTotal = grandTotal + targetCursor.Statement.Amount;
      		END IF;

            -- Delete the real Statement tree leaving only the bit stream version
            DELETE FIELD targetCursor.Statement;

            -- Step onto the next Invoice, removing the previous invoice and any
            -- text elements that might have been interspersed with the Invoices
      		REPEAT
                MOVE sourceCursor NEXTSIBLING;
                DELETE PREVIOUSSIBLING OF sourceCursor;
            UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE)
        END REPEAT;

            -- If there are no more invoices to process, abandon the loop
            IF NOT LASTMOVE(sourceCursor) THEN
                LEAVE InvoiceLoop;
      		END IF;

        END LOOP InvoiceLoop;
    END ProcessInvoice;

    -- Remove the temporary source and target folders
  		DELETE FIELD OutputRoot.MRM.SourceMessageTree;
  		DELETE FIELD OutputRoot.MRM.TargetMessageTree;

    -- Finally add the grand total
  		SET resultCursor.GrandTotal = grandTotal;
  		
  		-- Set the output MessageType property to be 'Data'
  		SET OutputRoot.Properties.MessageType = 'Data'; 
 
               RETURN TRUE;
	END;

CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
        SET I = I + 1;
END WHILE;
	END;

  END MODULE;
관련 개념
메시지 플로우 개요
ESQL 개요
메시지 모델링
관련 태스크
메시지 플로우 설계
메시지 플로우 컨텐츠 정의
ESQL 파일 관리
메시지 모델 개발
큰 XML 메시지 핸들링
관련 참조
Compute 노드
Database 노드
Filter 노드
ASBITSTREAM 함수
CREATE문
SET문
주의사항 | 등록상표 | 다운로드 | 라이브러리 | 지원 | 피드백
Copyright IBM Corporation 1999, 2006 마지막 갱신 날짜: 2006/08/21
ac20702_