¿Es seguro el subproceso HttpSession? ¿Se establecen / obtienen operaciones seguras de subprocesos de atributo?
-
03-07-2019 - |
Pregunta
Además, el objeto que se está configurando debe ser seguro para subprocesos para garantizar que sepamos cuál es el estado del objeto almacenado en la sesión.
También, estaba leyendo en la web que algunos sugieren usar:
synchronized(session) {
session.setAttribute("abc", "abc");
}
¿Es esta una sugerencia válida?
Solución
No, no están a salvo de subprocesos, según IBM - teoría y práctica de Java : ¿Están rotas todas las aplicaciones web con estado? . Necesitas sincronizar.
Cómo HttpSession no es seguro para subprocesos de Java Ranch también podría ser útil.
Otros consejos
Servlet 2.5 spec:
Servlets múltiples ejecutando solicitud hilos pueden tener acceso activo a la mismo objeto de sesión al mismo tiempo. El contenedor debe garantizar que manipulación de datos internos estructuras que representan la sesión atributos se realiza en una Hilo seguro. El desarrollador tiene la responsabilidad de threadsafe Acceso a los objetos de atributo. sí mismos. Esto protegerá el colección de atributos dentro de la Objeto HttpSession de concurrente Acceso, eliminando la oportunidad. para una aplicación para hacer que colección para corromperse.
Esto es seguro:
// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);
Esto no es seguro:
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);
Esto no se garantiza que sea seguro:
// 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);
}
He visto este último enfoque recomendado (incluso en los libros J2EE), pero no está garantizado que funcione con la especificación de Servlet. Podría usar el ID de sesión para crear un mutex , pero debe haber un mejor enfoque.
No. Y como no desea que el mismo cliente (con sesión) realice solicitudes simultáneas, debe serializar estas solicitudes como AbstractController hace en Spring MVC
De alguna manera, esto depende del diseño de su cliente.
¿Tiene la oportunidad, en su diseño web, de que un solo cliente tenga múltiples solicitudes simultáneas pendientes utilizando la misma sesión HTTP? Esto parece difícil de hacer a menos que se vincule una única sesión HTTP a múltiples sockets. (también conocido como AJAX) Aparte de hacer esto, el acceso HTTP de un cliente determinado será de un solo hilo en lo que respecta al servidor, lo que significa que una sola sesión es efectivamente segura para subprocesos.
La sincronización de los objetos de su sesión hará que la aplicación sea más segura frente a los cambios futuros que hacen que su aplicación web sea capaz de tener múltiples solicitudes simultáneas, por lo que no es una mala idea. En las implementaciones modernas de Java, la sincronización no tiene el gran costo que anteriormente se asociaba con ella, especialmente cuando la sincronización generalmente no está controlada. Si su aplicación utiliza AJAX, lo que implica que espera múltiples solicitudes simultáneas en vuelo a su servidor web, entonces la sincronización es una necesidad.
No lo son, pero la mayoría de las veces, sus clientes solo accederán a ellos con un solo hilo.
Los diferentes clientes tendrán subprocesos diferentes y cada uno tendrá su propia sesión.
Como señala Eddie, una situación en la que puede enfrentar dos hilos que acceden a la misma sesión es que dos llamadas ajax intentan modificar el mismo atributo de sesión. De lo contrario no tendrás problemas.
La sesión no es segura para subprocesos y tampoco se garantiza que los métodos get y set no sean seguros para subprocesos. En general, en un contenedor de servlets debe asumir que se encuentra en un entorno de múltiples hilos y ninguna herramienta proporcionada es segura.
Esto también se aplica a los objetos que almacena en la sesión. La sesión en sí no manipulará el objeto almacenado, pero puede recuperar el objeto en un hilo diferente e intentar manipularlo. Depende de usted examinar su propio código para ver si las condiciones de carrera son posibles.
El ejemplo de código que publicaste es válido, pero el problema puede existir más allá del alcance limitado de tu ejemplo. Asegura que no hay condiciones mientras se configura en la sesión, pero no hay nada que impida que otro subproceso anule el conjunto. Si el código en su solicitud depende del valor que permanece sin cambios, todavía podría estar en problemas.