Concurrency Utilities for Java EE
Concurrency Utilities for Java™ EE es un modelo de programación asíncrono que le permite enviar o planificar tareas para su ejecución en paralelo, crear hebras que hereden el contexto Java EE y transferir el contexto Java EE a la invocación de interfaces tales como las devoluciones de llamadas asíncronas.
Concurrency Utilities for Java EE puede mejorar el rendimiento, al permitir que un programa Java EE descomponga las operaciones en tareas paralelas.
- Contexto de seguridad
- Contexto de internacionalización
- Contexto de área de trabajo
Interfaces de Concurrency
Concurrency Utilities for Java EE proporciona cuatro tipos principales de recursos, cada uno de los cuales puede configurarse y pasar a estar disponible en JNDI:
- Servicio de ejecutor gestionado
- Las aplicaciones utilizan un ejecutor gestionado para enviar tareas asíncronas que puede empezar a ejecutar como hebras, normalmente desde una agrupación, cuando los recursos pasan a estar disponibles para ejecutarlas. Las tareas son instancias de Callable o Runnable. Se da a la aplicación un futuro, desde el que puede comprobar el estado y obtener o esperar el resultado de la finalización de tareas. El ejecutor gestionado incluye interfaces para enviar y esperar la finalización de un grupo de tareas o de una tarea en un grupo. Las tareas heredan el contexto de la hebra que envía la tarea.
- Servicio de ejecutor planificado gestionado
- Las aplicaciones utilizan un ejecutor planificado gestionado para planificar tareas asíncronas para iniciar la ejecución tras un punto específico en el tiempo. Las tareas son instancias de Callable o Runnable. El ejecutor planificado gestionado incluye interfaces para la replanificación automática de una tarea, con un intervalo fijo o calculado según la lógica empresarial personalizada. Las tareas heredan el contexto de la hebra que planifica la tarea.
- Fábrica de hebras gestionadas
- Las aplicaciones utilizan una fábrica de hebras gestionadas para crear nuevas hebras que heredan el contexto del componente de la aplicación que ha buscado o inyectado la fábrica de hebras heredada.
- Servicio de contexto
- Las aplicaciones utilizan un servicio de contexto para construir proxies contextuales, lo que permite las invocaciones de una o varias interfaces de proxy para heredar el contexto de la hebra que ha creado el proxy.
Transacciones
Se llama a cada tarea enviada o planificada, hebra de fábrica de hebras gestionadas y operación de proxy contextual con cualquier transacción que estaba anteriormente en la hebra suspendida, de la misma forma que las transacciones gestionadas por contenedor en enterprise beans típicos. Esta situación es muy parecida a cuando se llama a un método EJB (Enterprise JavaBeans) con TX_NOT_SUPPORTED. El tiempo de ejecución inicia un contenedor de transacciones locales antes de invocar el método. La tarea puede iniciar su propia transacción global si esta transacción es posible para el componente Java EE de llamada. Puede alterar temporalmente este comportamiento para proxies contextuales especificando la propiedad de ejecución TRANSACTION con un valor de USE_TRANSACTION_OF_EXECUTION_THREAD. La propiedad permite que la transacción permanezca en la hebra de ejecución para que las operaciones transaccionales realizadas en el método de proxy puedan confirmar y retrotraer junto con la transacción de la hebra invocada.
Cuando llama a un bean de entidad desde dentro de una tarea, por ejemplo, debe tener un contexto transaccional global disponible en la hebra actual. Debido a que las tareas inician contextos transaccionales locales, puede encapsular cada lógica de bean de entidad en un bean de sesión que tenga un método marcado como TX_REQUIRES o equivalente. Este proceso establece un contexto de transacción global desde el que puede acceder a uno o más métodos de bean de entidad.
Acceso a metadatos del componente Java EE
Si una tarea tiene un componente Java EE, como por ejemplo un bean de sesión, sus propios metadatos están activos cuando se llama al método. Si una tarea es un objeto Java simple, los metadatos del componente Java EE del componente de creación están disponibles para el bean. Al igual que su hebra de envío, la tarea puede buscar el espacio de nombres java:comp, java:module y java:app. Esta búsqueda permite al bean acceder a recursos como por ejemplo orígenes de datos, fábricas de conexiones y enterprise beans, del mismo modo en que lo haría cualquier otro componente Java EE. Las propiedades de entorno del componente de creación también están disponibles para la tarea.
El espacio de nombres java:comp es idéntico al que hay disponible para el componente creador y se aplican las mismas restricciones. Por ejemplo, si el enterprise bean o servlet tiene una referencia a EJB java:comp/env/ejb/MyEJB, esta referencia a EJB está disponible para la tarea.
Gestión de conexiones
Una tarea puede utilizar los orígenes de datos y las fábricas de conexiones que su componente Java EE de creación ha obtenido mediante las referencias de recursos java:comp. (Para obtener más información sobre las referencias de recursos, consulte el tema Referencias.) Sin embargo, el método de bean debe acceder a estas conexiones utilizando el patrón get, use o close. No hay almacenamiento en memoria caché de conexiones entre llamadas de método en una tarea asíncrona. Las fábricas de conexiones o los data se pueden guardar en la memoria caché, pero las conexiones se deben recuperar, utilizar y cerrar finalmente cada vez que se llama al método. Mientras que la tarea puede buscar fábricas de conexiones y orígenes de datos utilizando un nombre JNDI (Java Naming and Directory Interface) global, no se recomienda por las razones siguientes:
- El nombre JNDI está codificado en la aplicación (por ejemplo, como propiedad o literal de serie).
- Las fábricas de conexiones no se comparten ya que no se puede especificar un ámbito de compartimiento.
Si desea ver ejemplos de código que muestren las formas correctas e incorrectas de acceder a conexiones desde tareas, consulte el tema Ejemplo: Gestión de conexiones de simultaneidad.
Inicio diferido de tareas contextuales
Concurrency Utilities for Java EE da soporte al inicio diferido permitiendo la serialización de la información de contexto de hebras Java EE. Los proxies contextuales son serializables si la instancia proporcionada al método ContextService.createContextualProxy es serializable. En este punto, el servicio de contexto crea una instantánea de los contextos Java EE habilitados en el gestor de trabajo. A continuación, se puede serializar y almacenar el proxy contextual resultante en una base de datos o un archivo. Esto es útil cuando es necesario almacenar contextos de servicio Java EE, tales como la identidad de seguridad actual o el entorno local y, posteriormente, inflarlos y ejecutar alguna tarea en este contexto. Todos los métodos de interfaz del proxy contextual se ejecutan con el contexto de hebras capturado previamente.
Todos los proxies contextuales deben ser deserializados por la misma ejecución que los ha serializado. Todos los EJB y clases deben estar presentes para que Java expandir correctamente los objetos que contienen.
Inicio diferido y seguridad
El contexto del servicio de seguridad podría requerir que la aserción de identidad de Common Secure Interoperability Versión 2 (CSIv2) esté habilitada. Se requiere la aserción de identidad cuando el proxy contextual se deserializa y se ejecuta en la asignación de credenciales de identidad de asunto de JAAS (Java Authentication and Authorization Service). Consulte los temas siguientes para comprender mejor si necesita habilitar la aserción de identidad cuando se utiliza un objeto proxy:
- Configuración del protocolo de autenticación Common Secure Interoperability Versión 2 y Security Authentication Service
- Aserción de identidad
Existen también limitaciones en la interoperatividad con proxies contextuales entre distintas versiones del producto.
Limitaciones relacionadas con JPA
El uso de tareas asíncronas en un contexto de persistencia ampliada JPA no está soportado.
Un contexto de persistencia ampliado JPA no es consistente con las posibilidades de planificación y multihebra de Concurrency Utilities for Java EE y no será accesible desde una tarea asíncrona.
Asimismo, una tarea asíncrona no debe aceptar un javax.persistence.EntityManager (o subclase) como parámetro ya que las instancias de EntityManager no están pensadas para que tengan seguridad de hebra.