Le thread HttpSession est-il sûr, les opérations set / get relatives aux threads d'attributs sont-elles sécurisées?

StackOverflow https://stackoverflow.com/questions/616601

Question

De plus, l'objet en cours de définition doit-il être thread-safe pour garantir que nous savons quel est l'état de l'objet stocké dans la session?

En outre, je lisais sur le Web que certains suggèrent d'utiliser:

synchronized(session) {
  session.setAttribute("abc", "abc");
}

Est-ce une suggestion valable?

Était-ce utile?

La solution

Non, ils ne sont pas thread-safe, selon IBM - Théorie et pratique de Java : Toutes les applications Web avec état sont-elles endommagées? . Vous devez synchroniser.

Comment HttpSession n'est pas thread-safe Java Ranch pourrait également être utile.

Autres conseils

Spéc. Servlet 2.5:

  

Demande d'exécution de plusieurs servlets   les discussions peuvent avoir un accès actif à la   même objet de session en même temps.   Le conteneur doit assurer que   manipulation de données internes   structures représentant la session   attributs est effectuée dans un   manière threadsafe. Le développeur a   la responsabilité de threadsafe   accès aux objets d'attribut   se. Cela protégera le   collection d'attributs à l'intérieur du   Objet HttpSession de concurrent   accès, éliminant l'occasion   pour une application qui cause   collection à corrompre.

Ceci est sans danger:

// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);

Ceci n'est pas sécurisé:

HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);

Cela n'est pas garanti d'être sûr:

// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
  Integer n = (Integer) session.getAttribute("foo");
  session.setAttribute("foo", (n == null) ? 1 : n + 1);
}

J'ai vu cette dernière approche préconisée (y compris dans les livres J2EE), mais la spécification Servlet ne garantit pas qu'elle fonctionne. Vous pouvez utiliser l'ID de session pour créer un mutex , mais il faut une meilleure approche.

Non. Et comme vous ne voulez pas que le même client (avec session) effectue des requêtes simultanées, vous devez sérialiser ces requêtes comme suit: AbstractController fait dans Spring MVC

D'une certaine manière, cela dépend de la conception de votre client.

Avez-vous la possibilité, dans votre conception Web, qu'un seul client ait plusieurs demandes simultanées en attente utilisant la même session HTTP? Cela semble difficile à faire à moins d’attacher une session HTTP unique à plusieurs sockets. (aka, AJAX) À part cela, l'accès HTTP d'un client donné sera mono-thread pour le serveur, ce qui signifie qu'une seule session est effectivement sécurisée pour les threads.

La synchronisation de vos objets de session sécurisera l'application contre les modifications futures rendant votre application Web capable de recevoir plusieurs demandes simultanées. Ce n'est donc pas une mauvaise idée. Dans les implémentations Java modernes, la synchronisation n'a pas le coût élevé qui lui était associé auparavant, en particulier lorsque la synchronisation n'est généralement pas contrôlée. Si votre application utilise AJAX, ce qui implique que vous attendiez plusieurs demandes simultanées en vol sur votre serveur Web, la synchronisation est indispensable.

Ils ne le sont pas, mais la plupart du temps, vos clients n’y accéderont qu’avec un seul thread.

Différents clients auront différents threads et chacun aura sa propre session.

Comme le souligne Eddie, deux threads accédant à la même session peuvent être confrontés à deux appels ajax tentant de modifier le même attribut de session. Sinon, vous n'aurez pas de problèmes.

La session n'est pas thread-safe et ni les méthodes get, ni set ne sont garanties comme étant thread-safe. En général, dans un conteneur de servlets, vous devez supposer être dans un environnement multi-thread et qu'aucun outil fourni n'est sûr.

Ceci s’applique également aux objets que vous stockez dans la session. La session elle-même ne manipulera pas l'objet stocké mais vous pouvez récupérer l'objet dans un autre thread et tenter de le manipuler. Il vous appartient d’examiner votre propre code pour voir si des conditions de concurrence sont possibles.

L'exemple de code que vous avez publié est valide, mais le problème peut exister au-delà de la portée limitée de votre exemple. Cela garantit qu'il n'y a pas de conditions lors de la définition de la session, mais rien n'empêche un autre thread de remplacer l'ensemble. Si le code de votre demande dépend de la valeur restante inchangée, vous pouvez toujours rencontrer des problèmes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top