Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    servlet, session e concorrenza

    Ciao a tutti.
    Stiamo realizzando una applicazione Web e ci troviamo di fronte a dei problemi di concorrenza.
    L'applicazione realizzata in java prevede l'uso di controller strutturati nel seguente modo:
    controllerX --(estende)--> SuperController --(estende)--> HttpServlet

    E' capitato, raramente, che in casi di stress del server alcuni dati di un utente X venivano visualizzati da un utente Y.
    Quello che non ci è chiaro ora è come tomcat gestisce le istanze delle servlet. Cioè l'utente X e l'utente Y eseguono lo stesso codice su una medesima istanza? o viene creata una servlet dedicata per il singolo utente?

    Per comprendere meglio la situazione devo tuttavia fare alcune specifiche. Il superController ha delle proprietà private, come ad esempio un BeanUtente che contiene appunto i dati dell'utente.

    Googlando un po ho trovato alcune persone che sconsigliavano vivamente l'uso di variabili locali nelle servlet, a meno che non si tratti di variabili in "sola lettura" o la servlet non sia stata definita come "SingleThreadModel"(deprecato).
    Questo conferma la mia ipotesi, cioè tomcat istanzia una sola classe servlet che viene poi utilizzata da tutti gli utenti contemporaneamente.

    E' possibile gestire questa problematica senza perdere il parallelismo dell'applicazione? ........qualsiasi commento o informazione sull'argomento sarebbbe molto apprezzato.

    ciaoooooooooooo
    Esistono solo 10 tipi di persone al mondo.....quelli che conoscono il binario e quelli che non lo capiscono!

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320

    Re: servlet, session e concorrenza

    Originariamente inviato da SyLaR_is_back
    Questo conferma la mia ipotesi, cioè tomcat istanzia una sola classe servlet che viene poi utilizzata da tutti gli utenti contemporaneamente.
    Non solo Tomcat... questo è parte integrante della specifica Java Servlet API. Qualunque servlet-container si deve comportare in questo modo (anche gli Application Server). Il lifecycle di una servlet è il seguente:

    Al verificarsi di una richiesta che richiede una servlet, il Servlet Container si comporta così:

    1) Verifica se esiste già un'istanza della servlet. Se non esiste
    1.a) Carica la classe della servlet
    1.b) Istanzia la servlet
    1.c) Inizializza la servlet

    2) Richiama il metodo invoke() dell'oggetto servlet.

    Da qui: http://docs.oracle.com/javaee/6/tutorial/doc/bnafi.html

    Dunque, esiste una ed una sola istanza di ciascuna Servlet.

    E' possibile gestire questa problematica senza perdere il parallelismo dell'applicazione? ........qualsiasi commento o informazione sull'argomento sarebbbe molto apprezzato.

    ciaoooooooooooo
    In che senso? E' chiaro che quando si progetta una WebApp si deve sapere come funziona il meccanismo delle servlet.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Ciao e grazie della risposta.
    Magari è una domanda stupida ma quello che non ho capito è: esiste una ed una sola istanza per ogni servlet a livello globale o per il singolo utente?

    Nello specifico il mio problema è questo.
    Ho una classe ControllerX che come prima cosa prende l'id utente dalla classe BeanUtente salvato nella sessione.
    Poniamo ke l'id dell'utente X sia 000.
    Successivamente la servlet fa dei controlli e altre cosette sue.
    E prima di chiamare la nuova pagina chiama un metodo che (tramite facade, bo e dao) arriva sul db e carica una lista di oggetti, che verranno visualizzati poi sulla pagina.
    questo metodo prende come parametro proprio l'id utente.
    E' possibile che l'id venga sporcato da un ipotetico utente Y che si collega nell'arco temporale tra il getID dalla session e la chiamata di quel metodo? questo spiegherebbe perche alcune volte (casi rarissimi) l'utente X visualizza i dati dell'utente Y, cioè la funzione di caricamento dati viene chiamata con l'id di qualcun'altro

    Utente X chiama servlet
    .....
    idUtenteX = 000 (getID dalla sessione dell'utente X)
    ...
    ....*Utente Y chiama servlet
    ....*idUtenteY = 111 (getID dalla sessione dell'utente Y)
    .....
    listaObj = caricaLista_UtenteX(111)
    ...
    nuova pagina....

    Quello che mi preme sapere è se effettivamente l'utente X e quello Y scorrono la stessa porzione di codice, cioè se lavorano sulla stessa istanza della servlet. Spero di essere riuscito a spiegare il problema
    Esistono solo 10 tipi di persone al mondo.....quelli che conoscono il binario e quelli che non lo capiscono!

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da SyLaR_is_back
    Ciao e grazie della risposta.
    Magari è una domanda stupida ma quello che non ho capito è: esiste una ed una sola istanza per ogni servlet a livello globale o per il singolo utente?
    A livello globale. Il ServletContainer è uno ed uno solo: Tomcat.

    Nello specifico il mio problema è questo.
    Ho una classe ControllerX che come prima cosa prende l'id utente dalla classe BeanUtente salvato nella sessione.
    Poniamo ke l'id dell'utente X sia 000.
    Successivamente la servlet fa dei controlli e altre cosette sue.
    E prima di chiamare la nuova pagina chiama un metodo che (tramite facade, bo e dao) arriva sul db e carica una lista di oggetti, che verranno visualizzati poi sulla pagina.
    questo metodo prende come parametro proprio l'id utente.
    E' possibile che l'id venga sporcato da un ipotetico utente Y che si collega nell'arco temporale tra il getID dalla session e la chiamata di quel metodo? questo spiegherebbe perche alcune volte (casi rarissimi) l'utente X visualizza i dati dell'utente Y, cioè la funzione di caricamento dati viene chiamata con l'id di qualcun'altro

    Utente X chiama servlet
    .....
    idUtenteX = 000 (getID dalla sessione dell'utente X)
    ...
    ....*Utente Y chiama servlet
    ....*idUtenteY = 111 (getID dalla sessione dell'utente Y)
    .....
    listaObj = caricaLista_UtenteX(111)
    ...
    nuova pagina....

    Quello che mi preme sapere è se effettivamente l'utente X e quello Y scorrono la stessa porzione di codice, cioè se lavorano sulla stessa istanza della servlet. Spero di essere riuscito a spiegare il problema
    Le servlet, per loro natura, non sono thread-safe. Questo significa che è compito del programmatore evitare situazioni in cui due thread diversi (ovvero, due richieste simultanee diverse) si pestino i piedi a vicenda. La cosa si ottiene usando solo variabili locali (ciascun thread che invoca i metodi della servlet avrà la sua copia dello stack). Se si usano variabili "globali", ovvero di istanza per la servlet, vanno usate in modo molto cauto.

    La regola aurea è quella di non usare variabili di istanza per memorizzare informazioni relative ad una richiesta, bensì usare le variabili locali e/o gli attributi di sessione.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.