Select language:

Idempotent Web Services

Use

Synchronous Web services that are marked as idempotent are executed exactly once.

When systems communicate asynchronously, the SAP message exchange infrastructure can ensure reliable messaging, including guaranteed delivery and exactly-once execution of each message. This holds true irrespective of whether the message exchange is brokered by SAP Process Integration using the XI 3.0 protocol, or it is performed using the WS-RM standard.

In synchronous communication, where services are called directly using the plain Web services protocol, there is no guarantee that each request message sent by the consumer arrives exactly once at the provider. It is possible to experience the following issues:

  • Undelivered request.

    A message may be lost or arrive several times in case of network problems.

  • Undelivered response.

    Even if the request message arrives at the provider, the response message may be lost during network transport. A consumer that does not receive a response in due time may assume that its request did not arrive and resend its request.

For many synchronous services, however, it is crucial that the service is successfully executed exactly once when requested. For example, if a new purchase order shall be created via a service invocation, it is neither acceptable to have no purchase order created, nor to have two or more duplicates created due to repeated processing of exactly the same request. In general, all services that change the persistent state of an application should support exactly-once execution. All request-response operations are of this category. A mechanism is necessary for these services, which guarantees that a service is successfully executed exactly once when it is requested by a consumer.

SAP NetWeaver provides a framework that allows ensuring synchronous service calls are executed exactly once. Web services that use this framework are referred to as "idempotent". The framework can be used to do the following:

  • It stores a message created in response to an incoming service call before the response is actually sent to the consumer.

  • The service response is identified by the request message's ID. For each incoming request, the provider can determine if the exact same request has already been processed by checking if a response for the request ID has been stored. If this is the case, the framework can directly return the response created earlier without reprocessing the request.

  • When an idempotent service receives exactly the same request message multiple times within a limited time frame, it processes it only once and returns the original response. The framework takes care of locking the response store. It also removes stored responses after a certain period to prevent the accumulation of unnecessary data in the database.

  • When the execution of a request-confirmation service is unsuccessful the service can be executed again. The first execution attempt may have been unsuccessful because of temporary issues (for example, locking conflicts), and a repeated execution could be successful.

Note

The object of exactly-once handling is to avoid incorrect business processes and data, and not to improve performance. Query-response services that only serve to read or find data thus should not support exactly-once execution.

Considerations for Service Consumers

It is assumed that the framework used by the Web service consumer application waits for a response for a certain period of time, and informs the consumer application when the time for waiting is exceeded. Irrespective of whether this is implemented using an exception or other mechanism, the consumer application regains control. This way, the consumer application can decide to retry sending exactly the same request message, thus prolonging the "waiting time".

It is important that this retry decision must be incorporated in the consumer application's logic, using appropriate consumer application code, model. If retry is already supported by the underlying framework, the retry decision must be implemented by appropriate parameterization of the call to the framework when issuing the (first) service call.

The decision may not be left to the normal user. Consider the result if the user waits for too long or decides not to retry, and at the same time the first request was executed by the service provider and only the response was lost. Simply returning to the user interface (or process) step that triggered sending the original request and thus allowing the user to manually retrigger the communication is not an appropriate approach. Such a retriggering must lead to a new request with a new request message UUID.

Note that resending messages may also be caused by failures of network or infrastructure components.