Return to Home Page
Overview
    History
    Acknowledgements
    Podcasts
    Notification Form
    Feedback Form
    Press Release #1
    Press Release #2
    Press Release #3

Master SOA Design
Pattern Catalog
    Master Pattern List (alphabetical)
    Master Pattern List (by category)
    Master Pattern List with
Page Numbers (PDF)
    Master Pattern List (Text)
    Pattern Notation
    Pattern Profiles
    Symbol Legend
    Pattern Contribution Form

SOA Candidate Patterns
    SOA Patterns Review Committee
    Candidate Patterns Overview
    Candidate Patterns List
    Candidate Pattern Contribution Form
    Candidate Pattern
Feedback Form
    SOA Pattern Template

Design Pattern Basics
    What's a Design Pattern?
    What's a Design Pattern Language?
    What's a Compound Pattern?

Supplemental
    SOA Patterns and Application Technologies
    SOA Design Patterns Historical Influences
    SOA Design Patterns and Design Principles
    SOA Design Patterns and Design Granularity
    Legal

Resources
    Design Patterns Publications
    Reference Posters
    SOAPrinciples.com
    WhatIsSOA.com
    SOA Visio Stencil

About the Book



SOA Design Patterns
by Thomas Erl

For more information visit: www.soapatterns.com

Related Publications


"Introducing SOA Design Patterns", SOA World Magazine (PDF)



"The Case for Single-Purpose Services: Understanding the Non-Agnostic Context and a Strategy for Implementation", SOA Magazine (HTML)



"REST-Inspired SOA Design Patterns", SOA Magazine (HTML)



"Service-Orientation and Object-Orientation Part I: A Comparison of Goals and Concepts", SOA Magazine (HTML)



"Service-Orientation and Object-Orientation Part II: A Comparison of Design Principles", SOA Magazine (HTML)



"Service Facade", InformIT (HTML)



"Non-Agnostic Context", InformIT (HTML)



"Domain Inventory", InformIT (HTML)



"Service Normalization", InformIT (HTML)



"Service Decomposition", InformIT (HTML)



"Canonical Schema", InformIT (HTML)



"Policy Centralization", InformIT (HTML)





Idempotent Capability (candidate)


Home > Candidate Patterns List > Idempotent Capability

"How can a service capability be designed so that no unwanted side-effects are produced when the same request is received more than once?"

Problem

When a service consumer sends a message to a service the message can be lost. A common scenario is that the consumer sends a request message but doesn’t get a corresponding response message back from the service. In this case there are three possible reasons that can explain the lack of a response message:
1. The request message was lost and therefore wasn't delivered to the service.
2. The response message was delivered to the service but something went wrong inside the service before a response message could be sent to the consumer.
3. The response message made it to the service and the service sent a response message back but the response message was lost and therefore wasn't delivered to the consumer.
4. The response message made it to the service and the service sent a response message back. The response message was delivered to the consumer but something went wrong inside the consumer before the response message could be processed.
If the consumer resends the request message when it concludes that the response message will not arrive everything should be fine if the service didn’t receive the request message that was sent before, as in case 1 above.

However, in case 2, 3 and 4 it may lead to that the service processes the same request more than once, in effect treating them as separate requests. Problems in intermediaries such as message queues or routers may also lead to a message being delivered more than once.

Solution

Use reliable transports with guaranteed message delivery and make sure that no messages are lost during processing, alternatively design service capabilities in such a way that if the same request is received multiple times the result is the same as if the request was received only once.

Application

When reliable transports are not an option there are two ways to achieve idempotency:
1. Design service capabilities in such a way that processing the same request multiple times will not produce unwanted side-effects.
2. Attach a unique id to each request and check that the request has not already been processed prior to processing the incoming request.

Impacts

May add extra development and / or design efforts for the service developers as well as the consumer developers.

Principles

Service Autonomy, Service Composability

Architecture

Service Architecture, Composition Architecture

Status

Under Review

Contributors

Herbjorn Wilhelmsen, Cesare Pautasso
 

Problem

When a service consumer sends a message to a service the message can be lost. A common scenario is that the consumer sends a request message but doesn’t get a corresponding response message back from the service. In this case there are three possible reasons that can explain the lack of a response message:

1. The request message was lost and therefore wasn't delivered to the service.
2. The response message was delivered to the service but something went wrong inside the service before a response message could be sent to the consumer.
3. The response message made it to the service and the service sent a response message back but the response message was lost and therefore wasn't delivered to the consumer.
4. The response message made it to the service and the service sent a response message back. The response message was delivered to the consumer but something went wrong inside the consumer before the response message could be processed.
If the consumer resends the request message when it concludes that the response message will not arrive everything should be fine if the service didn’t receive the request message that was sent before, as in case 1 above.

However, in case 2, 3 and 4 it may lead to that the service processes the same request more than once, in effect treating them as separate requests. Problems in intermediaries such as message queues or routers may also lead to a message being delivered more than once.

Which kind of problems could this lead to?

For capabilities that create new data (e.g. the REST method POST) resending a request will create duplicate data entries.

For capabilities that read data (e.g. the REST method GET) resending a request may create problems if the consumer pays per read.

For capabilities that update data (e.g. the REST method PUT) resending a request may create a problem if the consumer expects a particular response, e.g. a message that confirms that the original read data was unchanged and that the new data was saved successfully.

For capabilities that delete data (e.g. the REST method DELETE) resending a request may create a problem if the consumer expects a particular response, e.g. a message that confirms that the data was deleted.

In a more real world complex scenario imagine that your service needs to perform a credit worthiness check of a customer. You send a request to another service and patiently wait for the response, but it doesn’t arrive. You then decide to resend the request. If the service that performs the actual credit worthiness check receives the request twice and treats them as different requests it will perform two credit check operations on your behalf. You have to pay for two credit worthiness checks when you only wanted one. Additionally, one of the terms that is used when adjudging the credit worthiness of a person or a company is actually how many credit checks that have been performed on that same person or company within a period of time. This is important part in the credit worthiness criteria as it allows companies that offer credit a change to avoid giving credit to a customer at the same time that a lot of other companies also give credit to that same customer. The customer may then buy a lot of things on credits from different companies and then disappear. So, if your request is treated as two separate requests this may lead to an incorrect credit worthiness report on your customer. It can lead to big problems for your customer – your customer is now considered not credit worthy! It can also lead to that your company refuses to take part in a perfectly legitimate business deal.



Solution

There are basically two ways of solving this kind of problem. One is to use transports that guarantee the deliveries of all related messages and also making sure that no message is lost inside your service if something should happen when a message is being processed.

The other solution is to make your capability idempotent.



Idempotency defined

In mathematics an operation is said to be idempotent if applying the operation multiple times does not change the result. For instance the absolute value of a number is an idempotent operation. The absolute value of a number can be thought of as the distance from zero on a scale. This operation is idempotent since

abs(x) == abs(abs(x))

Example: abs(-1)==(abs(abs(-1)) as the absolute value of -1 is 1 and the absolute value of 1 is 1.

In SOA we can be a little less strict about the definition of idempotency. For instance if you perform a read operation it could be considered idempotent even if reading the data again gave a slightly different result as long as it didn’t produce any side-effects, in other words: A capability can be said to be idempotent if applying the capability multiple times yields the same result as applying it only once.



Application

Built in Idempotency

Capabilities that change data may be possible to design in a way that makes them idempotent by the nature of their logic. If you call a capability that allows you to update the address of a customer you typically send a message to the service containing the customer id and the new address. If you resend the message the end result will be that the customer address is saved two times, but the address that you wanted your customer to have is saved correctly. The capability is idempotent.

In distributed systems with a lot of potential users you may have to design such a capability in another way. Consider that you first read the consumer address from the service, correct a problem with the address and then want to save it. If another person just saved a new customer address, maybe due to a call from the customer that requested an address change, you would not want your minor correction to be saved since that would change the address that your colleague just saved. Instead you must be notified that your changes were not saved since the customer address has a different value compared to the one that you initially got from the service. This kind of scheme is often referred to as optimistic locking. If you try to save the address twice though, you would be notified the second time that you cannot save the address – somewhat annoying as you actually have succeeded in saving the address. You could then add to your locking behavior and return a success message to the consumer if the save was successful or if the consumers address is identical to the “change” that the consumer requested.

Idempotency through unique message ids

Capabilities that cannot have idempotency built into their logic can still be made idempotent by attaching unique ids to messages. This requires that the consumer of your service creates a unique id and then attaches that id to the message. Inside the service you may then store these message ids and by checking this storage you will be able to know if a message has been processed before and act accordingly. Using this information you can avoid problems that you may get into if the same message is processed several times as if you were actually dealing with different messages. For instance you can choose to not increment a counter, or avoid creating another (duplicate) copy of an order.

The consumer, though, may still require a response. If generating such a response message is a costful operation you could save the response message that you generated the first time the request message was processed and resend that response message to the consumer.

The Prentice Hall Service-Oriented Computing Series from Thomas Erl
Home    SOA Books    SOA Magazine    What is SOA?    SOA Principles    SOASchool.com    SOA Glossary Copyright © 2007-2009
SOA Systems Inc.