Question

I'd like to know the correct / best way to handle concurrency with an Axis2 webservice.

Eg, given this code:

public class MyServiceDelegate
{
    @Resource
    UserWebService service; // Injected by spring

    public CustomerDTO getCustomer()
    {
       String sessionString = getSessionStringFromCookies();
       service.setJSESSIONID(sessionString);
       CustomerDTO customer = service.getCustomerFromSessionID();
    }
}

Note that in the above that UserWebService is a 3rd party API. The service requires that when making calls, we pass a cookie with the JSESSIONID of an authenticated session.

Am I correct in assuming that this statement is not threadsafe? IE., given two threads, is it possible for the following to occur?

  • ThreadA : service.setJSESSIONID("threadA")
  • ThreadB : service.setJSESSIONID("threadB")
  • ThreadA : service.getCustomerFromSessionID // service.sesionID == "threadB"

If so, what's the most appropriate way to handle this situation? Should I use a resource pool for service? Or should I declare service as synchronized?

    public CustomerDTO getCustomer()
    {
       synchronized( service ) {
          service.setJSESSIONID(sessionString);
          CustomerDTO customer = service.getCustomerFromSessionID();
       }
    }

Or, is there another, more appropriate way to handle this problem?

Was it helpful?

Solution

Would each thread have its own Delegate object and hence its own UserWebService service?

In the simple case, if delegates are created on the stack the threads would be independent.

If the cost of creation is high, have a pool of the delegate objects. Taking one from teh pool is comparativley cheap. You need to be very careful with housekeeping, but effectively this is what is done with database connections. Some environments have utility classes for managing such pooling - tends to be preferable to rolling your own.

OTHER TIPS

Is UserWebService one of your classes? If so, I think I'd change the method signature to:

public CustomerDTO getCustomer()
{
      CustomerDTO customer = service.getCustomerFromSessionID(sessionString);
}

And not have your UserWebService maintain state, that way it will be inherently thread-safe

As you said, the function is not thread safe. Java has a simple way to make monitors, which is an object that only allows one thread to access a function at a time. More info on monitors

To make it thread safe you can put synchronized either, as you did, around the expression, or before the function name:

public synchronized CustomerDTO getCustomer(){
    service.setJSESSIONID(sessionString);
    CustomerDTO customer = service.getCustomerFromSessionID();
}

The difference between the two is which object you turn into a monitor.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top