0% encontró este documento útil (0 votos)
111 vistas135 páginas

Guía de Enterprise Java Beans

Este documento describe Enterprise Java Beans (EJB), que son componentes de lógica de negocio que se ejecutan en el servidor. Existen dos tipos principales de EJB: Session Beans, que encapsulan lógica síncrona, y Message Driven Beans, que consumen mensajes de forma asíncrona. Los Session Beans pueden ser stateless, stateful o singleton dependiendo de si mantienen estado. Los EJB aprovechan servicios del contenedor como inyección de dependencias, manejo de transacciones y concurrencia.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
111 vistas135 páginas

Guía de Enterprise Java Beans

Este documento describe Enterprise Java Beans (EJB), que son componentes de lógica de negocio que se ejecutan en el servidor. Existen dos tipos principales de EJB: Session Beans, que encapsulan lógica síncrona, y Message Driven Beans, que consumen mensajes de forma asíncrona. Los Session Beans pueden ser stateless, stateful o singleton dependiendo de si mantienen estado. Los EJB aprovechan servicios del contenedor como inyección de dependencias, manejo de transacciones y concurrencia.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Taller de Sistemas de

Información 2
Enterprise Java Beans
Enterprise Java Beans
• Son componentes server side
• Encapsulan lógica procedural
• Típicamente representan procesos y/o reglas del negocio
• Integran un stack que resuelve entre otras cosas:
• Mensajería, acceso remoto, web services, inyección de dependencias, ciclo de
vida, transaccionalidad, manejo de excepciones, seguridad, etc.
• En la versión actual, aspectos que antes eran propietarios, ahora son
estándar
• Nombrado JNDI
Tipos de EJB
• Existen dos grandes tipos de componentes
• Componentes que encapsulan lógica sincrónica y componentes
basados en mensajería
• Los primeros, son los Session Beans
• Tienen funciones que encapsulan la lógica de negocio
• Los segundos, son los Message Driven Beans
• Estos son componentes que actúan como consumidores de mensajes JMS
• Permiten implementar lógica de negocio asíncrona y desacoplada
Session Beans
• Stateless
• No mantienen estado conversacional
• No presentan problemas de concurrencia
• Stateful
• Mantienen estado conversacional
• No presentan problemas de concurrencia
• Singleton
• Se mantiene una sola instancia del bean, compartiendo el estado
• Implementan efectivamente el patrón singleton
• Pueden presentar problemas de concurrencia
Session Beans
• Los tres tipos de componentes tienen características en común, como
ser el modelo de programación
• En algunos casos, estos pueden actuar como endpoints de servicios
web
• Servicios SOAP
• Servicios REST / Recursos
Servicios del container
• Comunicación remota
• Inyección de dependencias
• Manejo del estado
• Pooling
• Ciclo de vida del componente
• Mensajería
• Gestión de transacciones
• Seguridad
• Soporte para concurrencia
• Interceptores
Ejemplo
Anatomía de un Session Bean
• Un EJB suele estar compuesto por una clase de implementación (clase
del bean) y cero o mas interfaces de negocio
• Clase de implementación
• Contiene las implementaciones de los métodos de negocio
• Puede implementar cero o mas interfaces de negocio
• Debe esta anotada con: @Stateless, @Stateful o @Singleton
• Interfaces de negocio
• Contiene las declaraciones de los métodos de negocio visibles al cliente
• Son implementadas por el bean
Anatomía de un Session Bean
Clase de implementación
• Es cualquier clase Java que implementa la lógica del negocio
• Debe estar anotada con: @Stateless, @Stateful o @Singleton
• Debe implementar los métodos de su(s) interfaces
• Debe ser publica, no puede ser final o abstract
• No debe definir el método finalize()
• Los métodos no deben comenzar con “ejb” ni ser final o abstract
• Los argumentos y el tipo de retorno deben ser tipos validos RMI
Interfaces
• Un session bean puede implementar cero o mas interfaces
• Las interfaces pueden estar anotadas con alguna de estas anotaciones:
• @Remote: Indica una interfaz que será accedida remotamente
• @Local: Indica una interfaz que será accedida localmente (dentro de la JVM)
• @WebService: Indica que la interfaz será accedida por un web service SOAP
• @Path: Indica que la interfaz será accedida por un servicio REST (recurso)
• Una interfaz no puede estar marcada por mas de una anotación de
acceso a la vez
• En caso de no usar una interfaz, se asume que se accede localmente,
y a todos los métodos públicos del bean
Interfaces
Stateless beans
• Son el tipo de componente mas popular
• No manejan estado, lo que implica que (si nos interesa el estado), la
operación debe ser completada en una sola llamada
Stateful beans
• Permiten preservar el estado conversacional
• Son utiles para tareas que deben ser llevadas a cabo en varios pasos
• Por ejemplo, para implementar wizards
• Cada paso depende del estado generado por los pasos anteriores
• Un ejemplo típico puede ser un carrito de compras
Stateful beans
Stateful beans
• A diferencia del caso anterior (stateless), en este caso tenemos un
potencial problema de performance
• Un millón de clientes, se traducen en un millón de instancias para
cada bean
• Para evitar estos problemas, el container hace uso de los conceptos
de pasivado y activado
@[Link]
• Esta anotación asigna un timeout
• Es el máximo tiempo en el cual el bean puede estar ocioso
• Una vez superado el tiempo, el bean es removido del container
• La unidad se expresa según la anotación:
• [Link]
• El valor por defecto es MINUTE
@[Link]
• Esta anotación se aplica sobre el método checkout
• Una vez ejecutado este método, la instancia del bean es removida del
container
• Si no especificamos esta anotación, aun podemos contar con que el
Garbage Collector mande eliminar esta instancia
Singleton beans
• Es un bean que se instancia una única vez por aplicación
• Es una implementación del patrón Singleton, pero basada en session
beans, aprovechando los servicios brindados para el contenedor para
estos
Singleton beans
Inicialización de Singletons
• Existen situaciones en las cuales la inicialización de un singleton es
costosa
• Por ejemplo, si el CacheEJB anterior debiera poblarse con valores de
una base de datos, esto puede ser costoso de realizar
• No es una tarea para realizar en cada acceso al componente
• Podemos decirle al container que inicialice un Singleton al inicializar
con la anotación @Startup
Inicialización de Singletons
Encadenamiento de Singletons
• Existen situaciones en donde los datos de un singleton deben
provenir de otro singleton
• En este caso, es importante que el primero sea inicializado antes que
el segundo
• Para esto usamos la anotación @[Link]
Encadenamiento de Singletons
@DependsOn
• Utiliza una serie de strings como parámetros, donde cada una define
de que EJBs Singletons se depende
@DependsOn
• En caso de que los EJBs se encuentren en módulos diferentes, y
necesitemos realizar una referencia explicita a esto, podemos hacer…
Concurrencia
• La única instancia compartida puede sufrir acceso concurrente por
parte de los cliente
• La anotación @ConcurrencyManagement controla este acceso
concurrente por parte de los cliente
• Tenemos dos opciones:
• Container-managed concurrency (CMC)
• Bean-managed concurrency (BMC)
Container-Managed Concurrency
• Permite controlar el acceso concurrente
• Usamos la anotación @Lock, que puede tomar dos valores, READ
(Shared) o WRITE (Exclusive)
• @Lock([Link])
• No permite accesos concurrentes mientras la ejecución este en curso
• @Lock([Link])
• Solo permite otros accesos concurrentes, pero con el mismo tipo de lock
(READ)
Container-Managed Concurrency
• @Lock puede ser especificada en la clase, en el método o en ambos
• Si no especificamos el tipo de acceso, se asume
@Lock([Link])
• @AccessTimeout puede ser usado para determinar cuanto tiempo
esperar como máximo ante un lock que no puede ser obtenido
Container-Managed Concurrency
• Si un addToCache() se bloquea mas de 20 segundos, el cliente recibirá
una excepción de tipo ConcurrentAccessTimeoutException
• La unidad del valor especificado, se indica con el enumerado
TimeUnit
• En el caso anterior, esta es de tipo SECONDS
Bean-Managed Concurrency
• En este caso el container permite el acceso concurrente
• El programador es el encargado de controlar dicho acceso usando la
palabra clave synchronized
• Puede estar aplicada a nivel de método o como parte del código
usando un bloque synchronized
Concurrency Not Allowed
• Existen situaciones en donde no queremos permitir acceso
concurrente al bean
• Podemos usar @AccessTimeout para regular la espera por un lock
• Un valor de -1, indica que la espera debe ser indefinida
• Un valor de 0, indica que el acceso concurrente no esta permitido
• Puede generar condiciones de carrera
Inyección de dependencias
• Los EJB soportan inyección de dependencias
• Si el proyecto en el que se encuentran, incluye soporte CDI, entonces
las inyecciones pueden resolverse con las anotaciones de CDI (como
ser @Inject)
• En caso de no contar con un proyecto CDI, se proveen anotaciones
para inyectar los elementos mas comunes dentro de la plataforma
Inyección de dependencias
• @EJB
• Inyecta una referencia a un EJB especificado a través de la interfaz o de la
clase del bean
• @PersistenceContext y @PersistenceUnit
• Permite inyectar un EntityManager o una EntityManagerFactory,
respectivamente
• @WebServiceRef
• Inyecta una referencia a un servicio web
• @Resource
• Permite inyectar recursos, como datasources JDBC, connection factories de
JMS, el Timer Service, etc.
Session Context
• A veces es necesario que el componente acceda a los servicios que
provee el container
• Por ejemplo, validar manualmente un usuario
• Iniciar y/o commitear manualmente una transacción de negocio
• Para esto podemos inyectar una instancia de [Link]
• Podemos hacerlo con @Inject o @Resource
[Link]
JNDI
• Java Naming and Directory Interface
• Es un API que permite acceder a componentes EJB
• Es estándar, independiente del servidor de aplicaciones en donde los
componentes se encuentran instalados:
• java:<scope>[/<app-name>]/<module-name>/<bean-name>[!<fully-
qualified-interface-name>]
JNDI
• scope
• global: Permite que un componente externo acceda al namespace global
• app: Permite que un componente en una aplicación, acceda al namespace de
la aplicación
• module: Permite que un componente en un modulo acceda al namespace de
la aplicación
• comp: Es un namespace especifico para la aplicación, inaccesible desde el
exterior
JNDI
• app-name
• Solo se requiere si el componente esta dentro de un WAR o EAR
• El valor por defecto es el nombre del EAR o WAR sin la extensión
• module-name
• Es el nombre del modulo en el cual el session bean se encuentra instalado
• Puede ser un JAR o un WAR
• El valor por defecto es el archivo sin la extensión
JNDI
• bean-name
• Es el nombre del session bean
• Por defecto es el nombre de la clase
• fully-qualified-interface-name
• Es el nombre de la interfaz (nombre completo con package) por la cual se
accede al componente
• En el caso de no tener interfaces, este nombre puede ser el nombre completo
de la clase
JNDI
• Dentro de un WAR

• Dentro de un EAR
Deployment descriptor
• Los metadatos especificados en código (con anotaciones), pueden ser
configurados a través de archivos XML
• No son necesarios en la versión actual
• Esto se realiza en el archivo [Link]
• Este debe ubicarse en la carpeta META-INF del modulo EJB que
estamos instalando
Packaging
• Los EJBs deben ser empaquetados antes de ser instalados en el
servidor de aplicaciones
• En un modulo EJB generalmente encontramos
• La clase del bean
• Sus interfaces
• Cualquier clase auxiliar referenciada
• Excepciones que sean utilizadas
• El deployment descriptor (opcional)
Packaging
• Cuando colocamos estos artefactos en un modulo (JAR), podemos
colocar este dentro del servidor de aplicaciones
• Opcionalmente podemos colocar este modulo dentro de un archivo
EAR (el cual se coloca dentro del servidor de aplicaciones)
• El modulo que contiene los EJBs, se denomina modulo EJB
• También podemos colocar los EJBs directamente en un modulo WEB,
sin necesidad de separarlos en un ensamblado independiente
Invocando EJBs
• Cuando un componente no define interfaces de acceso
Invocando EJBs
• Si tenemos una interfaz de negocio implementada, debemos
especificar como accederemos
Invocando EJBs
• Si bien en este caso no es tan cómodo, podemos incluso buscar con el
nombre JNDI portable usando la anotación @EJB
Invocando EJBs
• En el caso de invocar a través de una búsqueda JNDI, podemos utilizar
@Produces
Invocando EJBs
• En el caso de invocar a través de JNDI un EJB, necesitamos utilizar la
interfaz Context
Invocando EJBs
• En el caso de Wildfly, las propiedades a incluir en el hashtable anterior
son:
• [Link]=[Link]
• [Link]=http-remoting://localhost:8080
• Usuario y password también pueden tener que especificarse si la
llamada es remota
• En una llamada local son opcionales
Invocando EJBs
• Para obtener una referencia remota al componente foo/bar en
Wildfly, debemos hacer…
Callbacks
• Como en el caso de los beans CDI, los componentes EJB tienen un
ciclo de vida asociado
• En dicho ciclo de vida, encontramos eventos, ante los cuales podemos
responder
• En el caso de que el bean sea implementado como un bean CDI,
podemos atender dichos eventos como fue visto en CDI
Stateless y Singletons

• Ambos tienen el mismo ciclo de vida


• No mantienen estado conversacional con
un cliente dedicado
• Ambos tipos de beans permiten el acceso a
cualquier tipo de cliente (con restricciones
de concurrencia en Singletons)
Stateful
• Son similares a los anteriores, pero con la diferencia que se mantiene
estado conversacional con un cliente dedicado
• 1000 usuarios simultáneos, generan 1000 instancias de Stateful
• El contenedor puede sacar una instancia de memoria si no es usada
por una cantidad de tiempo determinada
Stateful
• En algunos casos, los componentes abren conexiones JDBC o
conexiones de red
• Estos recursos no pueden ser mantenidos abiertos para cada
instancia de Stateful
• Debemos abrirlos y cerrarlos luego de activar y antes de pasivar un
componente
• También podemos desactivar el pasivado / activado con la siguiente
anotación:
• @Stateful(passivationCapable=false)
Callbacks disponibles
• Las siguientes anotaciones pueden ser aplicadas sobre métodos de
callback
• @PostConstruct
• @PreDestroy
• @PrePassivate
• @PostActivate
Reglas para un callback
• El método no debe devolver valores ni recibir parámetros
• No puede propagar checked exceptions, pero si puede propagar
runtime exceptions
• El método no puede ser static o final
• El método puede tener múltiples anotaciones, pero no podemos
tener dos métodos diferentes con la misma anotación
• Un método de callback puede acceder las environment entries del
bean
Llamadas asíncronas
• Por defecto las invocaciones a los métodos del bean son síncronas
• Podemos transformar la llamada a un método en asíncrona, usando la
anotación: @[Link]
• Es útil cuando tenemos métodos que sabemos de antemano que son
consumidores de tiempo
• Puede ser aplicada a nivel de clase o a nivel de métodos
Llamadas asíncronas
• Cuando un cliente invoca uno de estos métodos, el control se
devuelve al llamador
• La ejecución del método invocado continua en un thread aparte
• Existen sin embargo situaciones en las que debemos obtener un valor
resultado
• Usamos la anotación @[Link]<V>, donde V
representa el valor devuelto
Future<V>
• En el caso anterior, se devuelve un valor de este tipo
• El cliente puede recuperar el valor usando [Link]()
• Si por algún motivo se debe cancelar la operación, se puede invocar
[Link]()
• El container intenta cancelar, solo si la llamada asíncrona no ha iniciado aun
Future<V>
• El método invocado puede invocar el método
[Link]()
• Esto permite determinar si se solicito cancelar la innovación del
método asíncrono
• [Link]<V> es una implementación de Future<V>, que
permite devolver el valor al container
Interceptors
• Como en el caso de CDI, los componentes EJB son susceptibles de
intercepción
• Usamos las mismas anotaciones y conceptos presentados en el API
CDI para realizar intercepción de componentes
• Si no utilizamos CDI, entonces no podemos utilizar el
InterceptorBinding
• Pero todos los demás elementos presentados son utilizables
Timer Service
• Permite implementar notificaciones temporales
• Este servicio permite registrar notificaciones temporales para todo
tipo de beans, salvo para Stateful Beans
• Podemos notificar en base a:
• Una planificación basada en calendarios (calendar schedule)
• En un momento especifico
• Luego de un intervalo de tiempo
• O en intervalos de tiempo predefinidos
• Los timers pueden ser programáticos o automaticos
Timer Service
• Programmatic Timers
• Son establecidos explícitamente invocando alguno de los métodos de la
interfaz TimerService
• Automatic Timers
• Son creados automáticamente luego de un deploy exitoso
• Se crean en base a métodos que tengan las anotaciones @Schedule o
@Schedules
Timer Service
Calendar-Based Timer Expressions
• Ambos tipos de timers pueden ser establecidos en base a una
planificación basada en calendarios
• Se expresa en forma similar a las expresiones CRON o QUARTZ
• Existen multiples atributos que forman una de estas expresiones
• Al combinarlos se forma una calendar based timer expression
• dayOfMonth="Last“
• year="2011“
• month="July"
Calendar-Based Timer Expressions
• Podemos usar wildcards
• minute=”*”
• dayOfWeek=”*”
• También podemos especificar listas de valores
• Los duplicados se ignoran
• dayOfWeek=”Tue, Thu”
• hour=”4,9–17,22”
Calendar-Based Timer Expressions
• Rangos de valores
• Usamos el carácter “–”
• Los miembros no pueden ser wildcards, listas u otros rangos
• Un rango de la forma x–x es equivalente al valor x
• Un rango de la forma x–y, donde x es menor que y, incluye todos los valores
desde x a y
• Un rango de la forma x–y, donde y es mayor que x, incluye los valores desde x
al máximo valor, y luego desde el mínimo valor al y
• Ejemplos
• hour=“9–17“, dayOfWeek=“5–1”, dayOfMonth=”25–5”, dayOfMonth=“25–
Last,1–5”
Calendar-Based Timer Expressions
• Intervalos
• Usamos el carácter “/” para definir un intervalo
• Restringe un atributo a un valor inicial seguido de un intervalo regular
comenzando en dicho valor inicial
• Para la expresión x/y, x representa el valor inicial, y representa el intervalo
• En lugar de x podemos usar *, en este caso, x es igual a 0
• Los intervalos solo pueden definirse para horas, minutos y segundos
• Ejemplos
• minute=“*/10” equivale a minute= “0,10,20,30,40,50”
• hour=“12/2”
Programmatic Timers
• Cuando un timer programático expira, el container invoca el método
anotado con @Timeout, localizado en la clase de implementación del
bean
• El método @Timeout contiene la lógica de negocio que maneja el
evento temporizado
• Estos métodos …
• Deben retornar void
• No deben recibir parámetros o recibir un parámetro de tipo [Link]
• No pueden propagar Application Exceptions
Programmatic Timers
Programmatic Timers
• Para crear un timer, se invoca uno de los métodos “create” de la
interfaz TimerService
• Estos métodos permiten crear timers basados en calendarios, para
intervalos fijos, o para un único punto de tiempo
• Para timers basados en intervalos o en puntos fijos de tiempo, la
expiración del timer se expresa en milisegundos
• Podemos pasar los milisegundos o podemos crear un objeto
[Link] para indicar la fecha de expiración del timer
Programmatic Timers
Expira en un minuto

Expira en la fecha dada


Programmatic Timers
• Para las expresiones basadas en calendarios, debemos pasar al
método de creación del timer, una instancia de
[Link]
• Usamos el método [Link]
Programmatic Timers
• Los timers son persistentes por defecto
• Cuando el servidor se apaga o se cae, al reiniciarlo los timers se
reactivaran
• Si el timer expira mientras el servidor esta apagado, cuando el mismo
reinicie se invocara inmediatamente al método @Timeout
• Para crear un timer no persistente, debemos crear una instancia de
TimerConfig, pasarla como parámetro al timer, pero debemos invocar
• [Link](false)
Programmatic Timers
• Es importante tener presente que los timers, si bien tienen precisión
de milisegundos, la llamada al método de callback no tiene porque
ocurrir con la precisión del milisegundo
• Esto es porque los timers no están pensados para aplicaciones de
tiempo real
• Es típicamente usado para aplicaciones de negocio, en las que la
precisión se mide en días, horas, meses, etc.
Automatic Timers
• Cuando se realiza un deploy exitoso, en caso de existir métodos
anotados con @Schedule o @Schedules, el container crea los timers
automáticos
• Se pueden tener múltiples métodos anotados con @Schedule/s, a
diferencia de @Timeout
• El container marca el método como un método de timeout, de
acuerdo a la expiración indicada por la anotación @Schedule
Automatic Timers
• @Schedule soporta atributos para representar
• calendar expressions: utilizando los atributos antes vistos
• persistent: Indica si el timer automático debe sobrevivir caídas del servidor.
Por defecto, este tipo de timers son persistentes
• info: Permite establecer información descriptiva del timer
• timezone: Permite indicar que el timer esta asociado con una determinada
zona de tiempo. Esto permite alterar las expresiones de tiempo,
determinando contra que timezone ejecutan. Si no se especifica, se utiliza la
del servidor de aplicaciones
Automatic Timers
• @Schedules permite registrar múltiples expresiones de calendario
relacionadas con un método especifico
Cancelando timers
• Los timers se cancelan por alguno de estos motivos
• Cuando un timer asociado a un evento de única vez (en una fecha especifica)
expira. Se invoca el método de timeout y se cancela el timer
• Cuando se invoca el método cancel sobre la instancia del Timer. Los timers
pueden ser localizados a través de los métodos de búsqueda en la interfaz
TimerService
• Si cancelamos un timer ya cancelado, se propaga una excepción de
tipo [Link]
Salvando timers
• Si queremos salvar un timer para utilizarlo en el futuro, podemos usar
el TimerHandle asociado
• Sobre un objeto Timer, invocamos el método getHandle, para obtener
un objeto TimerHandler
• Este es serializable, por lo que puede ser salvado en una base de datos (por
ejemplo)
• Para obtener el Timer nuevamente, sobre el TimerHandle invocamos
el método getTimer
• Los TimerHandle solo pueden ser usados localmente
• No pueden ser pasados remotamente ni a través de web services
Información del timer
• Sobre una instancia de Timer, podemos además invocar estos
métodos
• public long getTimeRemaining();
• public [Link] getNextTimeout();
• public [Link] getInfo();
• getInfo() devuelve el objeto pasado como parámetro en la creación
del Timer
• Para obtener la colección de timers asociados con un bean,
invocamos sobre un TimerService inyectado, el método getTimers()
Transacciones y Timers
• Si los timers son creados dentro de una transacción, y esta
transacción hace rollback, entonces la creación del timer también se
deshace
• También si un timer es cancelado dentro de una transacción, y la
misma hace rollback, entonces la cancelación también se deshace
• La duración del timer no se ve afectada, como si el timer nunca
hubiese sido cancelado
Transacciones
• Una transacción es utilizada para asegurar que los datos manejados
por una aplicación, se mantienen en estado consistente
• Representa un grupo de operaciones, que deben ser realizadas como
una unidad
• Comúnmente se le denominan Unit Of Work
• Las transacciones siguen las propiedades denominadas ACID
Local vs Distributed Transactions
Two Phase Commit
Transacciones en EJB
• Como muchos otros servicios en los EJBs, cuando trabajamos con un
EJB, no debemos preocuparnos del transaction manager o de los
resource managers
• El container se encarga de todo esto por nosotros
• Las APIs dentro del container, abstraen la problemática del manejo
transaccional
• Java Transaction Service y Java Transaction API
Transacciones en EJB
• Uno de los aspectos mas importantes del manejo de transacciones en
los EJB, tiene que ver con el demarcado de la transacción
• Esto es, indicar el punto del programa donde comienza la transacción y donde
termina
• Asimismo, otro de los aspectos importantes a manejar, es indicar
como se propaga una transacción cuando invocamos uno u otro
método de un EJB
• Tenemos dos tipos de demarcado transaccional
• Container Managed Transactions
• Bean Managed Transactions
Container Managed Transactions
• Este manejo de las transacciones es totalmente declarativo
• En base a metadatos (anotaciones) en el código, podemos indicarle al
container cuando este debe arrancar y terminar una transacción
• El container provee este servicio a Session Beans (de cualquier tipo) y
a los Message Driven Beans
• El contexto transaccional del cliente no se propaga con llamadas a
métodos asíncronas
Container Managed Transactions
• En el ejemplo anterior, no se necesita ninguna anotación especial
para indicar que debemos manejar transacciones en el código
• Al utilizar configuración por excepción, se aplican los valores por
defecto para el manejo transaccional
• Esto es:
• Usar CMT
• Aplicar el nivel REQUIRED a cada método
Container Managed Transactions
• Por ejemplo, si el método createBook() NO ESTA dentro de una
transacción
Container Managed Transactions
• Por ejemplo, si el método createBook() esta dentro de una
transacción
@TransactionAttribute
• REQUIRED
• Indica que el método siempre debe ser invocado dentro de una transacción
• Si la invocación viene de un cliente no transaccional, el container inicia una
nueva transacción
• Sino, ejecuta en la transacción del cliente
• REQUIRES_NEW
• El container siempre crea una nueva transacción al invocar un método
• El éxito o no de esta nueva transacción, no afecta a la posible transacción
iniciada por el cliente
@TransactionAttribute
• SUPPORTS
• Si el cliente viene con una transacción, se utiliza esta
• En caso contrario, se ejecuta el método sin transacciones
• MANDATORY
• Indica que el método siempre debe ser invocado desde un cliente que haya
iniciado una transacción
• Si esto no es asi, se propaga una excepción de tipo
[Link]
@TransactionAttribute
• NOT_SUPPORTED
• El método del EJB no puede ser invocado desde un contexto transaccional
• Si el cliente viene con una transacción, se pone en pausa esta y luego se
invoca el método
• NEVER
• El método no debe ser invocado desde un cliente transaccional
• Si el cliente invoca desde un contexto transaccional, entonces se propaga la
siguiente excepción [Link]
CMT y Rollbacks
• En el caso de CMT, no podemos hacer rollback explícitamente, ya que
la demarcación es automática, al comienzo y fin del método
• Sin embargo, podemos decirle al container que a la transacción actual
se le debe hacer un rollback
• Usamos el método setRollbackOnly(), del SessionContext, el cual
puede ser inyectado a traves de @Resource
CMT y Rollbacks
• De la misma forma, debido que la transacción no se puede deshacer
inmediatamente, tenemos en el SessionContext, el método
getRollbackOnly()
• Este devuelve un booleano que indica si a la transacción actual se le
aplicara un rollback
• De esta forma, podemos evitar realizar tareas innecesarias, costosas
que serán deshechas al terminar el método
Excepciones
• Propagar una excepción dentro de EJB que utiliza transacciones, no
siempre deshace la transacción
• Esto dependerá del tipo de excepción y/o los metadatos asociados a
dicha excepción
• Tenemos 2 tipos de excepciones
• Application Exceptions
• System Exceptions
Excepciones
• Application Exceptions
• Son excepciones que representan problemas de la lógica de negocio
• Por ejemplo, “Inventario es escaso” o “No hay crédito”
• Por si solas, este tipo de excepciones no hace el rollback de la transacción
• Estas excepciones deben extender a [Link]
Excepciones
• System Exceptions
• Son excepciones causas por problemas a nivel del sistema, pero no de la
aplicación o el negocio
• Por ejemplo, errores en búsquedas JNDI, errores al acceder a la base de
datos, errores en la JVM, Null Pointer Exceptions, etc.
• Debe ser una subclase de RuntimeException o [Link]
• Propagar este tipo de excepciones, hace que la transacción sea marcada para
rollback
@ApplicationException
• Podemos usar esta anotación para indicar si la Application Exception
debe o no deshacer la transacción actual
Bean Managed Transactions
• Debemos usar la anotación TransactionManagement aplicada a la
clase del bean
Bean Managed Transactions
• La interfaz principal para manipular la transacción en el bean es
UserTransaction
• Esta puede ser inyectada a través de @Resource en la clase del bean
• Provee los métodos:
• begin, commit, rollback
• setRollbackOnly
• getStatus, setTransactionTimeout
• Un transacción nunca es propagada dentro de un método en un bean
con este tipo de manejo transaccional

También podría gustarte