2009-08-03 8 views
0

Je voudrais savoir la bonne/meilleure façon de gérer la simultanéité avec un webservice Axis2.Java simultané: Rendre l'accès webservice threadsafe

Par exemple, étant donné ce code:

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

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

Notez que dans ce qui précède que UserWebService est une API 3ème partie. Le service nécessite que lors de l'appel, nous passons un cookie avec le JSESSIONID d'une session authentifiée.

Ai-je raison de supposer que cette instruction n'est pas threadsafe? IE., Donné deux threads, est-il possible que ce qui suit se produise?

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

Si oui, quelle est la meilleure façon de gérer cette situation? Dois-je utiliser un pool de ressources pour le service? Ou devrais-je déclarer le service comme synchronisé?

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

Ou existe-t-il une autre façon plus appropriée de résoudre ce problème?

Répondre

3

Chaque thread aurait-il son propre objet Delegate et donc son propre service UserWebService? Dans le cas simple, si les délégués sont créés sur la pile, les threads seront indépendants.

Si le coût de création est élevé, disposez d'un pool d'objets délégués. Prendre un de la piscine est comparativement bon marché. Vous devez être très prudent avec l'entretien ménager, mais c'est effectivement ce qui est fait avec les connexions de base de données. Certains environnements ont des classes d'utilitaires pour gérer ce type de mise en commun - il est préférable de rouler les vôtres.

+0

Ceci est possible, mais semble cher. Actuellement, le délégué est déclaré comme un haricot de printemps, avec une portée singleton. Nous pourrions changer cela pour utiliser un prototype, instanciant ainsi le délégué et le service à chaque fois, cependant, cela semble beaucoup de frais généraux. Y a-t-il un meilleur moyen? –

+0

édité pour ajouter un design alternatif – djna

0

UserWebService est-il un de vos cours? Si oui, je pense que je changer la signature de la méthode à:

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

Et pas votre UserWebService maintenir l'état, de cette façon, il sera intrinsèquement thread-safe

+0

Malheureusement, non.Et le service exige qu'avant de passer un appel, nous définissons l'ID JSESSION sur le service afin qu'il puisse identifier la session authentifiée que nous utilisons. –

+0

Je suis en train de déduire que l'ID de session est quelque chose de défini sur l'objet délégué, puis un appelle le service distant, avec l'ID de session étant conceptuellement dans un cookie. Dans ce cas, les appels de fin de course laissent toujours la possibilité d'une course. – djna

0

Comme vous l'avez dit, la fonction n'est pas thread sécurisé. Java a un moyen simple de créer des moniteurs, un objet qui permet à un seul thread d'accéder à une fonction à la fois. Plus d'info sur monitors

Pour rendre thread-safe, vous pouvez mettre en mode synchronisé, comme vous l'avez fait, autour de l'expression, ou avant le nom de la fonction:

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

La différence entre les deux est l'objet que vous tournez dans un moniteur.

+1

Dans ce scénario, existe-t-il une raison de préférer une méthode synchronisée sur un pool de délégués (ou vice versa?) –

+2

La synchronisation pour la durée d'un appel de service Web me semble être une très mauvaise idée. Delegate Pool est la façon dont j'irais. – djna