views:

157

answers:

6

Let's say for example we've got a SIMPLE eCommerce system, with two separate systems: an Inventory Management System (IMS) and an Order Management System (OMS). Assume IMS provides information around inventory (getItem, getItemQuantities etc) and OMS provides ordering services (startOrder, addItemToOrder, finalizeOrder etc)

These two systems are implemented as web services using different backends. In OMS, assume a simplistic model like:

public class Order {
    private int orderId;
    private List LineItem;
    ...
}

public class LineItem {
    private int orderId;
    private int itemId;
    private int quantity;
    private int subTotal;
    ....
}

In IMS, assume a model like:

public class Category {
    private int catId;
    private List Item;
    ...
}

public class Item {
    private int itemId;
    .... (other attributes)
}

You can easily figure out a simple db table structure to implement the above.

As one use case, consider a client adding an item to an order. This request requires OMS to make several service/database calls:

  1. Validation of orderId (optional, can pass this responsibility to database).
  2. Call to IMS to validate passed-in itemId exists (required due to diff DB)
  3. Call to IMS to validate inventory against passed-in quantity (requred due to diff DB)
  4. Insertion of new record into table (required)

Does this make sense from a performance perspective? Can you think of a better way?


[EDIT]: As a followup, in the case where a user asks OMS for order details, it can only return orderId, and a list of orderLineItems each containing an itemId, quantity and subTotal. The client actually wants the item's name and description as well. Is the resposibility of retreiving the name/description to the client (through IMS) or is OMS responsible for this?

A: 

This could be done in a single service call, which could make a single database call to a stored procedure.

John Saunders
The question states that the two systems are separate. Additionally, using a stored procedure breaks a major goal of SOA (though that's not a stated issue in the question) by introducing tight coupling at the DB tier.
Eric J.
I used a stored procedure as an example of how the data layer could be implemented at the low level, to counter the suggestion that several database operations would be required.
John Saunders
A: 

From perfromance perspective I would have done this

A service for Validation of orderId.

A service called ValidatePlaceInDetails which does both validate passed-in itemId exists and validate inventory against passed-in quantity

A service for inserting new record into table.

we have reduced a service call by merging 2 and 3.

shivaspk
So we essentially lave the validation up to the order management services. Would you implement Aspects that sit around the method invocation that execute the validation logic? Or do you think the addItemToCart operations should be aware of validation requirements? I would lean towards the latter, but I'd like to see what you (and anyone else) think :)But it seems like in any case, the OMS is actually a *composite* web service?
djunforgetable
A: 

I see no problems with the system you have described, other than the fact that they are separate.

But if we imagine that this could not be done any differently and you are worried about performance, you could always implement some sort of caching to reduce the number of database lookups and to store the entire contents of the order in cache as well. The problem with caching is that in you case upon order submission a new bit more expensive database operation would have to be performed that would check if the ordered items are actually in stock, or alternatively just drop the unavailable items.

For a possible caching solution take a look at memcached.

Miha Hribar
The reason they are separate is simply so that the store doesn't come to a halt if the oms goes down. Users will still be able to visit the site and browse, just not be able to make any orders ...
djunforgetable
A: 

Since this is a SOA question I am curious why you are creating such strong dependencies between your application and webservices.

Why not use an ESB, there are some opensource ones now, that can enable you to just call the ESB with the order information, and the response would be an error or the order number and whatever else you need.

You abstract out everything else, as it is taken care of my the rules in the ESB.

One ESB I am experimenting with is: https://open-esb.dev.java.net/

The advantage is that you can swap out webservices, databases or add in new rules, without changing any code in your application.

This is very helpful if your application is distributed.

You can, ideally, put in some quality of service requirements, so orders from VIPs can go through faster than the regular people, and new users can go through even quicker, the first two times, so they can see how fast your system is.

There is a performance hit by adding in an ESB, but there are benefits such as looser coupling, that may make up for it, as you are now insulated from any changes outside of the wsdl for the ESB webservice.

James Black
A: 

I would make only one request to IMS with a request for checking if item X is actually in stock. If it's not a valid item, IMS should return some result code stating that I requested an invalid item. This way you save yourself a round trip to IMS. If the number of items I've requested is not in stock, then I would expect another result code stating that.

Jonathan van de Veen
+1  A: 

Forget SOA for a moment.

You've got two independent systems and at least one common operation that requires consistent updates to them both.

You need to consider not only checking the inventory but also decrementing it, and presumably that's only correct if the addition of the order line works.

How are you going to ensure that consistency? We can devise all manner of approaches (2PC transactions, or record reservations, or compensating transactions, or optimistic work with batch reconciliations) but in my view SOA or not, Web Services or not we still need to solve those problems.

Clearly for efficiency we want to reduce the number of communications between parts of the system requied to deliver the reuisite function. Hence the pattern of "check and do" as has been proposed. However such patterns, at least in their raw form, tend not to cope with the failure paths.

It may be best to come up with a few short-circuits. For example, we don't actually check the inventory when the order line is added. (Probably the UI already displayed the inventory so a comparatively recent check was already made) So instead we check the inventory when the order is finally placed, and then tell the user either "couldn't do it" or "you may need to wait a week or two for some bits, do you want to proceed".

With cunning we can make many operations only update one backend system for any one service invocation.

djna