El concepto de Java JTA genera muchas dudas y el otro día a través del blog me han preguntado si podía escribir un artículo sobre el tema. JTA (Java Transaction API) existe para generar una abstracción sobre la gestión de transacciones entre varios sistemas, permitiendo transacciones distribuidas.
Interfaces y Java Transacional Manager
JTA gestiona dos conceptos fundamentales: Uno es el de Transactional Manager que define como ha de implementarse un gestor de transacciones para ser compatible con JTA. Esto es algo de lo que deben preocuparse las empresas que implementan servidores de aplicaciones. El otro concepto son los JTA interfaces que delimitan los interfaces y anotaciones que los desarrolladores usan para gestionar las transacciones a nivel de código.
Java JTA Interfaces
Existen dos formas de trabajar con JTA a través de anotaciones lo que se denomina en el mundo de EJB Container Managed Transaction (CMT) o bien a través del uso de interfaces clásicos lo que se denomina Bean Managed Transaction (BMT). Este último usa el interface de UserTransaction que permite un control de la transacción mas a detalle. En nuestro caso vamos a implementar un ejemplo sencillo que use anotaciones. Empezaremos por construir un proyecto JPA que se encargue de mapear un Java Bean en la base de datos.
package com.arquitecturajava.bo; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Persona { @Id private String nombre; public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } }
Realizada esta primera operación el siguiente paso es configurar el persistence.xml para que se apoye en un dataSource previamente configurado con cada servidor de aplicaciones .
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="Persistencia"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:jboss/datasources/MySqlDS</jta-data-source> </persistence-unit> </persistence>
Java JTA y EJBs
Queda por construir un EJB que gestione una transacción a través del uso de anotaciones:
package com.arquitecturajava.ejb; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import com.arquitecturajava.bo.Persona; /** * Session Bean implementation class ServicioPersona */ @Stateless @LocalBean public class ServicioPersona { @PersistenceContext private EntityManager em; @TransactionAttribute(TransactionAttributeType.REQUIRED) public void insertar(Persona personaA,Persona personaB) { em.persist(personaA); em.persist(personaB); } }
Como se puede ver hemos definido un único método que se ejecuta de forma transaccional utilizando la anotación @TransactionAttribute que delega en JTA . En nuestro caso hemos construido un método que inserta dos Personas. Al ser el nombre la clave primaria de nuestra tabla si insertamos dos personas idénticas se producirá un rollback y ninguna de las personas será salvada en la base de datos.Invocaremos el EJB a través de un Servlet:
package com.arquitecturajava; import java.io.IOException; import java.io.PrintWriter; import javax.ejb.EJB; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.arquitecturajava.bo.Persona; import com.arquitecturajava.ejb.ServicioPersona;   @WebServlet("/ServletTransaccion") public class ServletTransaccion extends HttpServlet { private static final long serialVersionUID = 1L; @EJB ServicioPersona miservicio; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Persona a= new Persona(); a.setNombre("ana"); Persona b= new Persona(); b.setNombre("pedro"); miservicio.insertar(a, b); PrintWriter pw= response.getWriter(); pw.println("insertado"); } }
Como podemos ver usar JTA con nuestros EJBs es realmente sencillo.
Otros artículos relacionados:
Hola,
Alguien podria decirme como puedo ver desde java o por el log , las operaciones que van dentro de una determinada transaccion?
Saludos
Tendrás que activar los niveles de log a DEBUG y verás todo los tipos de trazas que se generen
Hola Celio.
Una duda quizás tonta pero estoy confundido y no encuentro una explicación para alguien mas lento como yo :p
qué diablos significa que un ejb sea transaccional? y qué demonios significa que el método sea transaccional @.@ estoy muy perdido!!!!!
Significa que se ejecuta dentro de una transacción , es decir si accede a la base de datos y persiste información con JPA , la operación será transaccional o se ejecutarán todas las operaciones o ninguna
Hola
Cuando en un método de Spring pongo la anotacion @Transactional, es por esta haciendo el uso del API DE JTA ?
esto tengo en mi applicationContext.xml
¿quien hace la transaccion ?Hibernate o Spring a través de JTA
gracias
La realiza Spring a traves del transaction manager que hayas configurado , pero este no es obligatorio que sea JTA.
[…] artículos relacionados: Introducción a JPA ,Introducción a JTA, SQL […]
[…] Otros artículos relacionados: El concepto de EntityManager , JPA Introducción , Introducción a JTA […]
[…] Otros artículos relacionados : Introducción a JPA , EntityManager , Introducción a JTA […]
Estimado, sabes trate de hacer ejercicios teniendo un Stateless que usa otros stateless y esos ultimos usan entities usando JTA sobre un wildfly, con un usuario no dio problemas pero cuando trate de usar mas de un usuario me dio esto y no le podido resolver tienes idea : 12:23:38,409 WARN [com.arjuna.ats.arjuna] (Transaction Reaper) ARJUNA012117: TransactionReaper::check timeout for TX 0:ffffc0a83801:-4dbfde6b:559175cc:12d in state RUN 12:23:38,412 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012095: Abort of action id 0:ffffc0a83801:-4dbfde6b:559175cc:12d invoked while multiple threads active within it. 12:23:38,412 WARN [com.arjuna.ats.arjuna] (Transaction Reaper Worker 0) ARJUNA012108: CheckedAction::check – atomic action 0:ffffc0a83801:-4dbfde6b:559175cc:12d aborting with 1 threads… Read more »
Me temo que no se me ocurre nada , asegurate que usaste las anotaciones correctas y no importaste alguna que tenía el mismo nombre pero era de otro paquete
Si esas anotaciones son correctas, de todas maneras muchas gracias por responder…
No habrás declarado el ejb como singleton o algo así?
me pasa lo mismo cuando guarda uno todo un exito pero cuando guarda mas de uno se raya, estoy trabajando con un plugin JTA que se llama atomikos, pero la verdad es que demora un poco a diferencia que lo hagas con JTA puro, no uso EJB solo JPA.
Dejo todo se propague atravez de la clase @Transactional e injecto el EntityManager con @Inject.
Segun los estandares de la empresa se debe usar atomikos pero no me funciona bien.
Alguna luz con atmikos?
No he trabajado con el , así que no te puedo decir
¿No estarás usando “orphanRemoval=true”?
Si es así, deberías cambiarlo a false, ya que el error ese que mencionas normalmente se manifiesta de esa manera.
Hola Cecilio,
Podrías aportar luz al tema de las XA trasactions? En que se diferencia de JTA.
Muchas gracias por tus aportaciones
me apunto la idea 🙂
Hola
que diferencia hay entre JTA y Bitronix
gracias
Es uno de los que implementa la especificacion de JTA 🙂
Mmmm, realmente no hace falta anotar el método ya que por defecto un EJB es transaccional:
http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html
Efectivamente yo simplemente lo he marcado por claridad. Pero la especificación lo deja claro. Si la transacción es requerida no hace falta la anotación
Genial!!! Encontre tu blog y estoy haciendo todos los ejericicos que tienes de JavaEE!!! =D
Cubres muchos de los vacios que tenia sobre esta tecnologia!!
Gracias!
de nada 🙂