Publicado el 13 de Febrero del 2019
434 visualizaciones desde el 13 de Febrero del 2019
66,2 KB
19 paginas
Creado hace 13a (23/02/2011)
Especialista Universitario Java Enterprise
Sesión 3: Transacciones
JMS y JavaEE
©2010-2011 Depto. Ciencia de la Computación e IA
Especialista Universitario Java Enterprise
Puntos a tratar
• Transacciones Locales
• Ejemplos Síncrono y Asíncrono
• Transacciones Distribuidas
• Conexiones Perdidas
• JMS y JavaEE
• Gestión de Recursos y Transacciones
• Ejemplo de EJB y Servlet
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 2
Especialista Universitario Java Enterprise
Transacciones Locales
• Un cliente JMS puede usar transacciones locales para agrupar bien
envíos o bien recepciones en operaciones atómicas.
• Para crear sesiones transaccionales, poner respectivamente a true
el primer argumento del método Connection.createSession().
Session session= connection.createSession(true, 0);
QueueSessionqueueSession= queueConnection.createQueueSession(true, 0);
TopicSessiontopicSession= topicConnection.createTopicSession(true, 0);
•
•
JMS no ofrece ningún método explicito de inicio de transacción.
• Nada más crear la sesión transaccional, la transacción ha comenzado.
JMS aporta los métodos Session.commit() y
Session.rollback() que pueden usarse en un cliente
• El commit significa que todos los mensajes producidos son enviados y se
envía acuse de recibo de todos los consumidos.
• El rollback implica que se destruyen todos los mensajes enviados y se
recuperan todos los mensajes consumidos y re-enviados aunque hayan
expirado.
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 3
Especialista Universitario Java Enterprise
Transacciones Locales (II)
• Toda transacción forma parte de una sesión transaccional.
• Tan pronto como se llama a commito rollback, finaliza una transacción y
comienza otra.
• Cerrar una sesión transaccional implica un rollbackautomático de la
transacción, incluyendo los envíos y recepciones pendientes.
• Los métodos anteriores no pueden usarse en EJBs ya que se usan
transacciones distribuidas.
• Podemos combinar varios envíos y recepciones en una transacción
local (no distribuída), pero en ese caso debemos tener en cuenta el
orden de las operaciones.
• Podemos realizar:
• varios sends
• varios receives
• o la recepción antes de enviar
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 4
Especialista Universitario Java Enterprise
No Hacer Esto…
• No hacer transaccional Request/Reply
• Siempre que enviemos un mensaje y esperemos recibirlo dentro de la
misma transacción el programa se colgará
• El envío no se hace efectivo hasta que no se hace un commit.
// No haceresto
outMsg.setJMSReplyTo(replyQueue);
producer.send(outQueue, outMsg);
consumer = session.createConsumer(replyQueue);
inMsg= consumer.receive();
session.commit();
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 5
Especialista Universitario Java Enterprise
…Por que
• al enviar un mensaje dentro de una transacción, realmente no se
envía hasta que no se realiza el commit.
• La transacción no puede contener ninguna recepción que
dependa de un mensaje enviado previamente.
• La producción y el consumo de un mensaje no puede ser parte de la
misma transacción ya que el intermediario es JMS, el cual interviene
entre la producción y la consumición del mensaje.
• Debemos hacer una transacción desde el productor al recurso JMS y otra
desde éste al consumidor.
• Producir y/o consumir mensajes dentro de una sesión puede ser
transaccional
• Pero producir y consumir un mensaje específico entre diferentes
sesiones no puede ser transaccional.
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 6
Especialista Universitario Java Enterprise
Ejemplo Síncrono
public void recibirSincronoPublicarCommit() throws JMSException {
Connection connection= null;
Session session= null;
QueueReceiverreceiver = null;
TopicPublisherpublisher = null;
try {
connection = connectionFactory.createConnection();
connection.start();
// Creamosunasesiontransaccional
session = connection.createSession(true, 0);
receiver = (QueueReceiver) session.createConsumer(queue);
publisher = (TopicPublisher) session.createProducer(topic);
TextMessagemessage = (TextMessage) receiver.receive();
System.out.println("Recibidomensaje[" + message.getText() + "]");
publisher.publish(message);
session.commit();
System.err.println("Rollbackpor" + jmse.getMessage());
session.rollback();
} catch (Exception e) {
System.err.println("Rollbackpor" + e.getMessage());
session.rollback();
publisher.close();
receiver.close();
session.close();
connection.close();
} catch (JMSExceptionjmse) {
} finally {
}
}
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 7
Especialista Universitario Java Enterprise
Ejemplo Asíncrono (I)
public void recibirAsincronoPublicarCommit() throws JMSException {
Connection connection= null;
Session session= null;
QueueReceiverreceiver = null;
TextListenerlistener = null;
try {
connection = connectionFactory.createConnection();
// Creamosunasesiontransaccional
session = connection.createSession(true, 0);
receiver = (QueueReceiver) session.createConsumer(queue);
listener = new TextListener(session);
receiver.setMessageListener(listener);
// Llamamosa start() paraempezara consumir
connection.start();
System.out.println("Finasincrono");
System.err.println("Rollbackpor" + jmse.getMessage());
session.rollback();
} catch (Exception e) {
System.err.println("Rollbackpor" + e.getMessage());
session.rollback();
receiver.close();
session.close();
connection.close();
} catch (JMSExceptionjmse) {
} finally {
}
}
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 8
Especialista Universitario Java Enterprise
Ejemplo Asíncrono (II)
private class TextListenerimplements MessageListener {
private Session session;
public TextListener(Sessionsession) {
}
public void onMessage(Messagemessage) {
this.session= session;
TopicPublisherpublisher = null;
TextMessagemsg= null;
// Consumimosy luegopublicamos
try {
msg= (TextMessage) message;
System.out.println("Recibidomensajeasincrono[" + msg.getText() + "]");
publisher = (TopicPublisher) session.createProducer(topic);
publisher.publish(message);
session.commit();
System.err.println("Rollbacken onMessage(): " + e.toString());
try {
} catch (JMSExceptionex) {
}
} catch (JMSExceptione) {
session.rollback();
}
}
}
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE- 9
Especialista Universitario Java Enterprise
TransaccionesDistribuidas
• Los sistemas distribuidos en ocasiones utilizan un proceso de two-
phasecommit (2PC) que permite a múltiples recursos distribuidos
participar en una transacción.
• estos recursos suelen ser BBDD, pero también pueden ser proveedores
de mensajes.
• El proceso de 2PC se realiza bajo el interfaz XA (eXtended
Architecture), y en JavaEElo implementa JTA ( Java TransactionAPI )
y los interfaces XA (javax.transaction y
javax.transaction.xa).
participar en transacciones distribuidas.
• La especificación JMS ofrece versiones XA de los siguientes objetos:
• Los proveedor JMS que implementan los interfaces XA puede
XAConnectionFactory, XAQueueConnection,
XAQueueConnectionFactory, XAQueueSession, XASession,
XATopicConnectionFactory, XATopicConnection y XATopicSession.
• El gestor de transacciones de un servidor de aplicaciones utiliza los
interfaces XA directamente, pero el cliente JMS solo ve las versiones
no-transaccionales.
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE-10
Especialista Universitario Java Enterprise
ConexionesPerdidas
• Si el proveedor JMS se cae debe intentar la reconexión. Si no lo
consiguiese, debe notificar al cliente de la situación, mediante el
lanzamiento de una excepción.
•
• ¿Problema? Un consumidor asíncrono no realiza ninguna llamada de
envío o recepción no llegar a detectar la pérdida de la conexión.
JMS ofrece el interfaz ExceptionListener paracapturar todas las
conexiones perdidas y notificar a los clientes de dicha situación.
publicinterfaceExceptionListener {
voidonException(JMSExceptionexception);
}
• El proveedor JMS se responsabilizaráde llamar a este método de
todos los listenersregistrados cuando no pueda realizar la reconexión
automática.
• El consumidor asíncrono podráimplementar este interfaz para poder
actuar en esta situación, e intentar la reconexión de modo manual
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE-11
Especialista Universitario Java Enterprise
Ejemplode ExceptionListener
private class ConsumidorAsincronoimplements ExceptionListener {
@Resource(mappedName= "jms/ConnectionFactory")
private static ConnectionFactoryconnectionFactory;
@Resource(mappedName= "jms/Queue")
private static Queue queue;
private Connection connection= null;
private void estableceConexion() {
try {
connection = connectionFactory.createConnection();
<strong>connection.setExceptionListener(this);</strong>
ex.printStackTrace(System.err);
} catch (JMSExceptionex) {
}
}
@Override
<strong>public void onException(JMSExceptionexception) {
System.err.println("Haocurridoun error con la conexion");
exception.printStackTrace(System.err);
this.estableceConexion();
}
public void recibeMensajeAsincronoCola() throws JMSException {
…
…
}
}
Servicios de Mensajes con JMS
©2010-2011 Depto. Ciencia de la Computación e IA
Transacciones, JMS y JavaEE-12
Especialista Universitario Java Enterprise
JMS en Aplicaciones JavaEE
• Los componentes weby EJBsno deben crear más de una sesión
• Cuando ut
Comentarios de: Sesión 3: Transacciones JMS y JavaEE - Servicios de Mensajes con JMS (0)
No hay comentarios