¿Es seguro el subproceso HttpSession? ¿Se establecen / obtienen operaciones seguras de subprocesos de atributo?

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

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?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top