views:

53

answers:

1

I am trying to use spring integration to decouple longer running action to get the response faster back to the user.

The request creates a gps position entry in our database. I want to do a http request do get the address of that gps position by reverse geocoding services. This can take a couple of seconds so I want to to it later/parallel.

Spring Integration works great for this, though the problem I have is that if the parallel running service is to fast a conflict occurs when saving the position entry in the database.

Is there a best practice on how to deal with persistent objects in Spring Integration? Should I try to lock the object until the main request is processed?

UPDATE:

basically I have two methods that manipulate my position object (pseudo Java code):

one that is in a Service class called by a MVC Controller:

void createPosition(float longitude, float latitude) {
  Position position = new Position(longitude, latitude);
  positionDao.save(position);
  locationChannel.send(new GenericMessage<Position>(position));
}

and on that is in a Service class called by a ServiceActivator attached to the locationChannel:

void getAddressForPosition(Position) {
  position.setAddress(/* get address via http request from openstreet or google */);
  positionDao.save(position);
}
A: 

If you can get away with it I would delegate also the position creation to the second thread. This way both parts of the unit of work can happen in the same transaction and you don't need to worry about orchestration.

  1. web thread: receive request
  2. web thread: send work message
  3. web thread: return response
  4. service thread: create position
  5. service thread: enrich position with address

With no ordering guarantees between 3 and 4,5. Then the client can check if the position was created correctly in a separate request.

An important consideration is to make the work idempotent, so you can resend the message if things went south without risking duplication.

iwein