Start of Content Area

Background documentation Transactions in the Asynchronous Receiver/Outbound Message Flow  Locate the document in its SAP Library structure

The adapter is part of the LUW of the Adapter Framework messaging service. This causes the following problem: The external adapter protocol uses its own local transaction, which is separate from the Adapter Framework database transaction. This problem can only be solved with a real two-phase commit global transaction, which is currently not available.

The MessageIDMapper is used instead. The processing sequence must contain the following steps:

...

       1.      Check whether the message ID is already saved in the MessageIDMapper.

       2.      Send the message to the external system.

       3.      Commit the send process if the external system has a transactional concept.

       4.      Use the MessageIDMapper to create a mapping between the external message ID and the XI message ID for the new message to be sent. The ID mapping is executed immediately as a nested LUW.

       5.      The Adapter Framework messaging service executes a commit of the LUW.

Caution

Although this procedure guarantees a near secure Exactly Oncedelivery and prevents data losses, duplicate entries may occur. If the server is shut down between the commit of the send process and the creation of the mapping, the XI message is sent twice. Therefore, the adapter must provide mechanisms to recognize such situations or enable the application to recognize duplicate entries at a later point in time.

Example

The JMS adapter sets the JMS CorrelationId to the XI message ID to enable the JMS client to recognize duplicate entries.

Example

The example shows the individual steps:

   public void sendMessage(Message message, IGUID xmbmsgid) throws Exception {

...

   String qos = (String) parameter.get(WorkerImpl.ATT_XIQualityOfService.name);

 

   // Step 1: First check whether this message was already received in case of EO(IO)

   if ( (qos.equalsIgnoreCase("ExactlyOnceInOrder")) ||

        (qos.equalsIgnoreCase("ExactlyOnce")) ) {

      if (messageIDMapper.getMappedId(xmbmsgid.toHexString()) != null) {

         //Just ignore the message, commit it if necessary and return

         return;

      }

   }

   // set correlation ID for duplicate detection

   message.setJMSCorrelationID(xmbmsgid.toString());

 

   // Step 2: Send JMS message. The JMS correlation ID can be used by the receiving

   // JMS application to detect the very rare XI duplicates (see below)

   try {

      externalSender.send(message);

   }

   catch (Exception e) {  // An exception causes the XI AF MS to rollback this message

      ...

      throw e;

   }

   // Step 3: Commit external protocol

   externalSession.commit();

      

 

   // Step 4: Save message ID mapping for duplicate recognition

   //Important: Use hex string XI message ID representation for PMI logging (inside mapper)

   messageIDMapper.createIDMap(xmbmsgid.toHexString(), jmsmsgid, System.currentTimeMillis() + 1000*3600*24);

 

   ...

 

   // Step 5: Return without exception = commit in XI AF MS

   TRACE.exiting(SIGNATURE);  

}

 

 

 

End of Content Area