2012-06-29 24 views
18

Estoy tratando de entender JTA y estoy usando Bitronix como el administrador de transacciones de su elección (solo por el bien de aprender y entender). Estoy mirando el código dentro del Bitronix reference guide here y me pregunto a mí mismo: Si estoy usando JDBC, que a su vez es transaccional (Connection puede confirmarse/retrotraerse), ¿por qué querría escribir código así? !?!Java EE: ¿Por qué usar JTA directamente?

Ahora tal vez el objetivo de ese fragmento de código era simplemente demostrar cómo usar Bitronix/JTA sobre un almacén de datos transaccional existente, pero aún no obtengo los beneficios inherentes que ofrece.

Luego, este fragmento de código me hizo pensar: "Si las dos únicas fuentes de datos principales que utiliza son bases de datos y intermediarios de mensajes, y usa JDBC/JMS para comunicarse con ellas, respectivamente, y estos dos estándares (JDBC/JMS) ya son transaccionales, ¿por qué necesitarías usar JTA en absoluto?!?! "

Es JTA una especie de API" interna "de Java EE que utilizan JDBC, JPA, JMS, etc. y solo está expuesto públicamente para el 1% de las personas que quieren hacer algo loco con eso? ¿O me estoy perdiendo la idea/aplicabilidad de JTA por completo?

Supongo que podría imaginar dos casos de uso no JDBC y no JMS para golpear JTA directamente, pero como soy muy confuso con JTA, en primer lugar no tengo idea si estos casos están desviados o no :

  • Quizás tenga un sistema de E/S complicado en su aplicación y tenga varios hilos que leen/escriben desde el mismo archivo en el disco. Tal vez debería hacer que cada hilo use una transacción para escribir en este archivo. (¿Sí?!? No?!?)
  • Quizás tenga una máquina de estados POJO que represente el estado de un sistema, y ​​varios hilos pueden modificar la máquina. Quizás tendrías que cada hilo usa una transacción para alterar el estado de la máquina.

supongo que en la raíz de mi pregunta es (Sí No?!?!?):

  • Si mi JPA (Hibernate) y/o las llamadas JDBC ya son transaccionales, ¿por qué habría de hacerlo ¿Quieres envolverlos dentro de JTA begin-> commit/rollback block? Lo mismo para JMS y sistemas de mensajería.
  • Fuera de JPA/JDBC/JMS, ¿qué casos de uso existen para usar JTA para realizar una serie de operaciones?

¡Gracias de antemano!

Respuesta

23

Es más que simplemente retrotraer la transacción abierta, JTA proporciona una interfaz XAResource que los proveedores pueden implementar, su controlador JDBC y su proveedor JMS ya lo harán y usted podrá implementar la suya propia. Esto se basa en un estándar abierto y probablemente valga la pena leerlo.

Ahora, ¿por qué querríamos esto?

Considere ejemplo Matthews en un desastre:

Begin DB Transaction 

Set AccountBalance $100 lower for Account #345 in database 

Add JMS Message "Transfer $100 to OtherBank Account #987" to queue 

*** DB power is unplugged while committing DB Transaction *** 

Desafortunadamente el mensaje JMS se ha ido a la otra orilla, este es un problema muy real con transacciones distribuidas.

Con XA Así es como el escenario se jugará:

DB Transation starts XA Transaction 

Set AccountBalance $100 lower for Account #345 in database 

JMS Connection joins XA Transaction 

Add JMS Message "Transfer $100 to OtherBank Account #987" to queue 

Everything went okay and JTA context is ready to commit. 

DB and JMS both agree that they are capable of commiting. 

JTA instructs DB and JMS to commit. 

All members of the transaction commit. 

Ahora usted puede preguntarse qué ocurre si el enchufe se saca durante la última DB cometió. Bueno, la cola JMS se habrá comprometido, sin embargo, la transacción XA permanecerá abierta hasta que el DB esté nuevamente disponible, momento en el que se volverá a instruir al DB para que se comprometa (el DB nos prometió que puede comprometerse, esto es parte de ser compatible con XA)

Lo que REALMENTE es genial acerca de JTA es que puede implementar fácilmente su propio XAResource personalizado y vincularlo a este gran marco.

ACTUALIZACIÓN

Así que para responder a su pregunta acerca de cuándo aplicar las transacciones personalizados puede preguntarse lo siguiente:

  1. es su estado personalizado o presentar incapaz de ser el bloque de código final en el alcance de la transacción?
  2. ¿Necesita revertir su estado/archivo personalizado cuando falla un sistema externo (es decir, DB o JMS)?
  3. ¿Es insuficiente getRollbackOnly() & setRollbackOnly() para sistemas externos, junto con el manejo de compensación (es decir, revertir estado/archivo personalizado explícitamente) para su código personalizado insuficiente?

Si la respuesta a ambas 1, 2 & 3 es sí, entonces usted quiere probablemente un encargo XAResource, de lo contrario creo que es algo excesivo.

Sin embargo, si su código es un marco o una biblioteca que se alistará por lógica de negocios en el espacio de Java EE, ¡puede implementar un XAResource para ello!

+0

Gracias por la excelente respuesta @Justin (+1). ¿Qué pasa con los ejemplos que estoy citando (lectura de archivos, manipulación de estados, etc.)? ¿Son aquellas instancias en las que uno quisiera realizar transacciones (por qué o por qué no)? Si es así, ¿tendría que implementar mi propio 'XAResource' para ellos? ** Nuevamente, para la recompensa, estoy buscando un conjunto de pautas para usar al decidir si se debe o no tramitar algo. ** ¡Gracias de nuevo! – IAmYourFaja

+0

@AdamTannon gracias por el +1! Agregué algunas de mis propias líneas de guía, espero que sean útiles. – Justin

+0

Awesome, awesome answer. ¡Gracias! – IAmYourFaja

3

Puede tener una transacción que cubra tanto la base de datos como el servicio de mensajes. No sé de ninguna manera de hacer eso sin JTA.

Ejemplo conceptual simple.El código exacto no es importante:

Comience JTA Transacción

Conjunto AccountBalance $ 100 inferior para la cuenta # 345 en la base de datos

Añadir mensaje JMS "Transferencia de $ 100 a la cuenta OtherBank # 987" hacer cola

Commit JTA Transacción

OtherBank es un banco independiente y asumimos se comunique con ella o ver JMS.

The Begin Transaction and Commit están a cargo de JTA. Si no se puede agregar a la cola, la extracción también se retrotrae automáticamente.

La vida real no es tan simple, pero esto debería darle una idea.

EDIT:

JTA se puede utilizar cualquier momento parte del sistema se puede aplicar correctamente el XAResource. Al implementar eso, un recurso puede participar en transacciones distribuidas. A primera vista, ambos ejemplos propuestos podrían implementar XAResource.

"un sistema de E/S complicado en su aplicación y tiene varios hilos que leen/escriben desde el mismo archivo en el disco". - Esto parece ser una base de datos, si lo piensas bien.

"Tal vez tiene una máquina de estados POJO que representa el estado de un sistema y varios hilos pueden modificar la máquina." - Esto definitivamente podría ser un candidato, si los cambios pueden aislarse lo suficiente.

Creo que la primera parte de la rúbrica es básicamente que los recursos lógicamente podrían ser XAResource s. En otras palabras, el concepto de ACID es significativo. El segundo es que es posible y vale la pena el esfuerzo implementar esa interfaz (donde aún no está implementada).

+0

Gracias Matt (+1) pero recuerde que soy completamente nuevo en JTA (y en la mayoría de los grados, Java EE en general). ¿Puede proporcionar un ejemplo de código de lo que está hablando (o ser más específico)? Supongo que no veo el "bosque a través de los árboles" aquí ... ¿por qué me gustaría tramitar el mismo conjunto de operaciones tanto para una base de datos como para un intermediario de mensajes? – IAmYourFaja

+0

@AdamTannon, soy nuevo en JTA también. Pero he proporcionado un ejemplo conceptual. –

+1

Ahhh, entonces JTA hace que las operaciones se puedan realizar en * recursos múltiples *, ¿sí?!? ¡Si eso es correcto, entonces lo "entiendo"! Gracias de nuevo – IAmYourFaja

0

En mi opinión, la primera consideración es descololar el administrador de TX y el sistema de TX.

Cuando diseño mi aplicación, la palabra Transactional marca mi intención de hacer algo ACID. Quiero poner esta intención en mi código comercial ya que esto debe ser impulsado por una necesidad comercial.

espero algo mágico (mi contenedor en la vida real) tejerá mis intenciones tx correctamente, en función del sistema que subyace TX (base de datos, JMS agente de bolsa, etc.)

Por otra parte, JTA define interfaces para permitir la integración somes entre un sistema JTA existente y un sistema TX (eventualmente nuevo, eventualmente exótico). Por ejemplo: GigaSpaces XAP es una cuadrícula de datos en memoria. No es JMS, no SQL, pero es fácil de usar como it provides a JTA integration. Podríamos citar muchos otros productos ...

Obviamente, el ejemplo asesino es el soporte para transacciones XA entre diferentes sistemas (le doy un punto a Justin). Mi punto es decir que JTA tiene valor incluso si no usas transacciones XA.