Monday, August 14, 2006

State in services architecture


I recently came across a post from Harry Pierson from Microsoft questioning the received wisdom that Services should be stateless. Harry makes a valid point that any meaningful business process has state and goes on to deduce that this implies that services should have state too.

I think Harry is missing the crucial point here by implicitly conflating business process and service state. In a good SOA ( and by good I mean one which delivers on the key promise of loose coupling), business processes indeed have state - they will be meaningless otherwise. However, there is a difference between process and service state.


In my view process state should not creep into services as this makes it difficult to replace service implementations over time and can lead to tight coupling in architectures. Ideally process state should be held in an intermediate metadata layer that forms part of the SOA infrastructure ( insert your favourite 3 letter flavour-of-the-month acronym in this sentence at this point - ESB being a prime candidate).


Service state is a different issue though. I think good SOA architectures should ensure that service state is kept inside the boundary and only exposed through contracts. This way, the service can truly deliver on the promise of being an independent blob of functionality that is independent of the context in which it is used. If this isn't the case in a specific instance, I would question the value in creating an SOA architecture.


To illustrate the point imagine a service that manages customers in any organisation. A CustomerManagement service in what I would see as good design would support an operation to return the status of a customer and would allow non specific states of the entity it manages to be tracked. For example, it may provide methods to change the state of a customer entity from enabled to disabled and have methods to return the current status. Note that such interactions cause the underlying entity to change state across all the processes that may be using the service. However, this still leads to loosely coupled architectures as the complete maintenance of this state lies inside the service so any change to state is only available to other servces through defined contracts.

Now consider an AddCustomer business process. In an organisation this may require a 3 day process that uses 3 manual steps including calls to the CustomerManagement Service above. Obviously keeping the state of this process inside a service makes it difficult to modify the process in the future - that is why the whole suite of BPM type tools ( including Microsoft's own Biztalk) exists. Typically one would model this process not in a service but as as some sort of orchestration using multiple services. The SOA infrastructure would manage the state of the process while the servces themselves would manage business state of the associated entities as indicated above.


This has gone on a bit but I think it is a crucial point which I summarise here in the form of some architecture principles :


- Services should only have state that is exposed through well defined contracts and makes sense in an Enterprise wide, cross-process sense ( like customer status).
- Service state should never creep outside the service boundary.
- Process state should ideally be maintained in infrastructure software - indeed it may form the justification for the purchase of such SOA infrastructure in an enterprise.
- Keeping process state in infrastructure and service state inside the boundary is key to creating loosely coupled, flexible architectures whilst supporting dynamic business processes.

6 Comments:

Anonymous Anonymous said...

The ACID properties come to mind - where in the follow "transaction" = "calls to a service"

ACID properties

When a transaction processing system creates a transaction, it will ensure that the transaction will have certain characteristics. The developers of the components that comprise the transaction are assured that these characteristics are in place. They do not need to manage these characteristics themselves. These characteristics are known as the ACID properties. ACID is an acronym for atomicity, consistency, isolation, and durability.

Atomicity

The atomicity property identifies that the transaction is atomic. An atomic transaction is either fully completed, or is not begun at all. Any updates that a transaction might affect on a system are completed in their entirety. If for any reason an error occurs and the transaction is unable to complete all of its steps, the then system is returned to the state it was in before the transaction was started. An example of an atomic transaction is an account transfer transaction. The money is removed from account A then placed into account B. If the system fails after removing the money from account A, then the transaction processing system will put the money back into account A, thus returning the system to its original state.

Consistency

A transaction enforces consistency in the system state by ensuring that at the end of any transaction the system is in a valid state. If the transaction completes successfully, then all changes to the system will have been properly made, and the system will be in a valid state. If any error occurs in a transaction, then any changes already made will be automatically rolled back. This will return the system to its state before the transaction was started. Since the system was in a consistent state when the transaction was started, it will once again be in a consistent state.

Looking again at the account transfer system, the system is consistent if the total of all accounts is constant. If an error occurs and the money is removed from account A and not added to account B, then the total in all accounts would have changed. The system would no longer be consistent. By rolling back the removal from account A, the total will again be what it should be, and the system back in a consistent state.

Isolation

When a transaction runs in isolation, it appears to be the only action that the system is carrying out at one time. If there are two transactions that are both performing the same function and are running at the same time, transaction isolation will ensure that each transaction thinks it has exclusive use of the system. This is important in that as the transaction is being executed, the state of the system may not be consistent. The transaction ensures that the system remains consistent after the transaction ends, but during an individual transaction, this may not be the case. If a transaction was not running in isolation, it could access data from the system that may not be consistent. By providing transaction isolation, this is prevented from happening.

Durability

A transaction is durable in that once it has been successfully completed, all of the changes it made to the system are permanent. There are safeguards that will prevent the loss of information, even in the case of system failure. By logging the steps that the transaction performs, the state of the system can be recreated even if the hardware itself has failed. The concept of durability allows the developer to know that a completed transaction is a permanent part of the system, regardless of what happens to the system later on.

from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnproasp2/html/acidproperties.asp

7:45 am  
Anonymous DevHawk said...

Piyush, I don't understand why you talk about "service" and "process" like they are different things. Sure, not all services implement long-running processes. But aren't all long-running processes going to be exposed as services? Assuming yes, than at least those long-running process services need to be stateful (in the HTTP sense of the word).

8:07 am  
Blogger Piyush said...

A transaction in a business process context is more than a call to a service though and frequently not ACID. The compensation logic that is frequently required to reverse the effects of a series of such calls is one of the many reasons preserving process state is so important.

8:08 am  
Blogger Piyush said...

Harry,
Not all running business processes need be exposed as services in my view. For example, ordering a chequebook in a bank may be a 5 day process involving lots of manual processing and paperwork and would not necessarily have a service entrypoint. Not all business processes are totally automated - some frequently involve large amounts of human workflow ( in microsoft/biztalk terminology) and that was the essence of my point.

The previous response was to "Anonymous" !

8:11 am  
Anonymous devhawk said...

I agree that a completely non-automated business process doesn't have a service entrypoint. :)

But you can automate a business process that has manual steps. Where does that business process live, if not in a service?

IMO, BizTalk is a host for long-running services. Sure, these services aren't always exposed as SOAP web services, but using SOAP isn't what makes something a web service. If you go by the 4 tenets of service-orientation defined by the WCC team, then EDI is service-oriented.

4:01 pm  
Blogger Andy said...

I too struggled with the concept of a process exposed as a service, since services are to be stateless, and processes are stateful.

I came to the current conclusion that a process instance living in a process management component (say a bpel engine), may be kicked off through a service invokation, and the process exposes services during its lifetime, which allow it to receive replies from other services it had called, but the process itself is not a service.

Maybe it can be thought of as mini stateful application which exposes services during its lifetime.

10:43 pm  

Post a Comment

Links to this post:

Create a Link

<< Home