Hay tres tipos de transacciones Java: transacción JDBC, transacción JTA (API de transacción Java) y transacción de contenedores. Transacciones de contenedores comunes como transacciones de resorte. Las transacciones de contenedores son proporcionadas principalmente por los servidores de aplicaciones J2EE. La mayoría de las transacciones de contenedores se completan en función de JTA. Esta es una implementación de API bastante compleja basada en JNDI. Por lo tanto, este artículo no discutirá las transacciones de contenedores por el momento. Este artículo presenta principalmente dos transacciones relativamente básicas en el desarrollo de J2EE: transacción JDBC y transacción JTA.
Transacciones JDBC
Todos los comportamientos, incluidas las transacciones, de JDBC, se basan en una conexión, y la gestión de transacciones se realiza a través del objeto de conexión en JDBC. En JDBC, los métodos relacionados con las transacciones comúnmente utilizados son: setAutocommit, compromiso, reversión, etc.
Aquí hay un código de transacción JDBC simple:
public void jdbctransfer () {java.sql.connection conn = null; Pruebe {conn = conn = drivermanager.getConnection ("jdbc: oracle: delgado: @host: 1521: sid", "username", "userpwd"); // Establezca la confirmación automática en falso, // si se establece en True, la base de datos reconocerá cada actualización de datos como una transacción y enviará automáticamente Conn.setAutOcommit (falso); stmt = conn.createStatement (); // Reduce la cantidad en la cuenta A por 500 stmt.execute ("/ actualización t_account SET CONTICIÓN = Cantidad - 500 Where Account_id = 'A'"); // Aumente la cantidad en la cuenta B por 500 stmt.execute ("/ update t_account establecer la cantidad = cantidad + 500 donde cuenta_id = 'b'"); // Enviar transacción conn.commit (); // Conjunto de transacción: la operación de dos pasos de la transferencia tiene éxito al mismo tiempo} Catch (SQLException SQLE) {try {// se produce una excepción, reversión () en esta transacción conn.rollback (); // reversión de la transacción: la operación de dos pasos de la transferencia revoca completamente stmt.close (); conn.close (); } catch (excepción ignore) {} sqle.printstacktrace (); }}El código anterior implementa una función de transferencia simple, que controla la operación de transferencia a través de transacciones, ya sea enviando o rodando hacia atrás.
Pros y contras de las transacciones JDBC
JDBC proporciona el soporte más básico para las operaciones de transacción de bases de datos utilizando Java. A través de las transacciones JDBC, podemos colocar múltiples declaraciones SQL en la misma transacción para garantizar sus características de ácido. La principal ventaja de las transacciones JDBC es que la API es relativamente simple, puede implementar las operaciones de transacción más básicas y el rendimiento es relativamente bueno.
Sin embargo, las transacciones JDBC tienen una limitación: ¡una transacción JDBC no puede abarcar múltiples bases de datos! ! ! Por lo tanto, si están involucradas múltiples operaciones de base de datos o escenarios distribuidos, las transacciones JDBC son impotentes.
Transacciones JTA
Por qué se necesita JTA
Por lo general, las transacciones JDBC pueden resolver problemas como la consistencia de los datos. Dado que su uso es relativamente simple, muchas personas solo saben que hay transacciones JDBC sobre las transacciones en Java, o que algunas personas saben sobre las transacciones en los marcos (como Hibernate, Spring), etc. Sin embargo, dado que JDBC no puede implementar transacciones distribuidas, y hay más y más escenarios distribuidos hoy en día, las transacciones de JTA emergen.
Si no encuentra escenarios de que las transacciones JDBC no se pueden resolver en el trabajo, entonces solo puede decir que los proyectos que está haciendo todavía son demasiado pequeños. Tome los sitios web de comercio electrónico como ejemplo. En general, dividimos un sitio web de comercio electrónico horizontalmente en módulos de productos, módulos de pedido, módulos de carrito de compras, módulos de mensajes, módulos de pago, etc. Luego implementamos diferentes módulos en diferentes máquinas, y cada módulo se comunica a través de llamadas de servicio remoto (RPC) y otros métodos. Brindar servicios al mundo exterior con un sistema distribuido.
Un proceso de pago debe interactuar con múltiples módulos, cada módulo se implementa en una máquina diferente y las bases de datos operadas por cada módulo son inconsistentes. En este momento, JDBC no puede usarse para administrar las transacciones. Veamos un código:
/ ** Procesamiento de la orden de pago **/ @Transactional (Rollbackfor = Exception.Class) public void CompletOrder () {ordendao.update (); // El servicio de pedido actualiza localmente el estado del pedido AccountService.Update (); // llame al servicio de cuenta de fondos para agregar puntos a la cuenta de fondos puntos de punto.update (); // Llame al servicio de puntos para agregar puntos a la cuenta de la cuenta de puntos cuenta cuenta cuenta de cuenta.insert (); // llame al servicio de contabilidad para escribir el comprobante de contabilidad original del sistema de contabilidad comerciante Merchantnotifyservice.notify (); // llame al servicio de notificación comercial para enviar la notificación de resultados de pago al comerciante}El código anterior es una operación de proceso de pago simple, en la que se llaman cinco servicios, todos los cuales se llaman a través de RPC. ¿Cómo garantizar la consistencia de la transacción usando JDBC? Agregué la anotación @Transactional al método, pero debido al uso de un servicio distribuido, la transacción no puede lograr el efecto del ácido.
Las transacciones JTA son más poderosas que las transacciones JDBC. Una transacción JTA puede tener múltiples participantes, mientras que una transacción JDBC se limita a una sola conexión de base de datos. Los componentes de cualquiera de las siguientes plataformas Java pueden participar en una transacción JTA: conexión JDBC, objeto JDO PersistenceManager, JMS Queue, JMS Topic, Enterprise Javabeans (EJB) y un asignador de recursos compilado con la especificación de arquitectura del conector J2EE.
Definición de JTA
Java Transaction API (JTA) es una versión de Java Enterprise de la interfaz del programa de aplicaciones. En el entorno Java, permite completar transacciones distribuidas en múltiples recursos de XA.
JTA y su Compatriot Java Transaction Service (JTS; Java TransactionService), proporcionan servicios de transacción distribuidos para la plataforma J2EE. Sin embargo, JTA solo proporciona una interfaz y no proporciona una implementación específica. En cambio, el proveedor del servidor J2EE lo proporciona de acuerdo con la especificación JTS. Hay varias implementaciones de JTA comunes:
1. Implementación de JTA (JBOSS) proporcionada por J2EE Container
2. Implementaciones independientes de JTA: como JOTM, Atomikos. Estas implementaciones se pueden utilizar en entornos que no usan servidores de aplicaciones J2EE para proporcionar garantías de transacciones distribuidas. Como Tomcat, Jetty y las solicitudes ordinarias de Java.
JTA proporciona java.transaction.usertransaction, que define los siguientes métodos.
Aquí, vale la pena señalar que las operaciones ordinarias de JDBC se pueden convertir directamente en operaciones JTA sin usar UserTransaction. JTA tiene requisitos para la fuente de datos, la conexión y los recursos. Solo las clases que cumplen con la especificación XA e implementan las interfaces relevantes de la especificación XA pueden participar en las transacciones JTA. Con respecto a la especificación de XA, consulte la introducción relevante en otro artículo en mi artículo. Aquí, permítanme mencionar que las bases de datos principales actuales admiten la especificación XA.
Para usar las transacciones JTA, necesita un controlador JDBC que implementa las interfaces javax.sql.xadataSource, javax.sql.xaconnection y javax.sql.xaresource. Un controlador que implementa estas interfaces podrá participar en las transacciones JTA. Un objeto XadataSource es una fábrica de un objeto Xaconnection. Xaconnection es una conexión JDBC que participa en las transacciones JTA.
Para usar las transacciones JTA, debe usar xadataSource para generar la conexión de la base de datos, y la conexión resultante es una conexión XA.
La diferencia entre la conexión XA (javax.sql.xaconnection) y la conexión no XA (java.sql.connection) es que XA puede participar en las transacciones JTA y no admite compromisos automáticos.
Código de muestra:
public void jtatransfer () {javax.transaction.userTransaction tx = null; java.sql.connection conn = null; Pruebe {tx = (javax.transaction.usertransaction) context.lookup ("java: comp/userTransaction"); // Obtener transacciones JTA, en este caso, el contenedor JBoss es administrado por javax.sql.dataSource ds = (javax.sql.dataSource) context.lookup ("java:/xaoracleds"); // Obtener el grupo de conexión de la base de datos, debe haber una base de datos y un controlador que admita XA que admite tx.begin (); conn = ds.getConnection (); // Establezca la confirmación automática en falso, // si se establece en True, la base de datos reconocerá cada actualización de datos como una transacción y enviará automáticamente Conn.setAutOcommit (falso); stmt = conn.createStatement (); // Disminución de la cantidad en la cuenta A por 500 stmt.execute ("/ actualizar T_ACCOUNT SET CONTICIONES = Monto - 500 Where Account_id = 'a'"); // Aumente la cantidad en la cuenta B por 500 stmt.execute ("/ update t_account establecer la cantidad = cantidad + 500 donde cuenta_id = 'b'"); // Aumente la cantidad en la cuenta B por 500 stmt.execute ("/ update t_account establecer la cantidad = cantidad + 500 donde cuenta_id = 'b'"); // Aumente la cantidad en la cuenta B por 500 stmt.execute ("/ update t_account establecer la cantidad = cantidad + 500 donde cuenta_id = 'b'"); // Conjunto de transacción tx.commit (); // Conjunto de transacción: la operación de dos pasos de la transferencia es exitosa al mismo tiempo} Catch (SQLException SQLE) {try {// Se produce una excepción, reversión () en esta transacción; // reversión de la transacción: la operación de dos pasos de la transferencia está completamente revocada stmt.close (); conn.close (); } catch (excepción ignore) {} sqle.printstacktrace (); }} El ejemplo anterior es una operación de transferencia utilizando transacciones JTA. Esta operación depende relativamente del contenedor J2EE y requiere que la transacción de usuario y la conexión se obtengan a través de JNDI.
Transacciones distribuidas estándar
Una transacción distribuida incluye un administrador de transacciones y uno o más gerentes de recursos. Un administrador de recursos es un almacén de datos persistente de cualquier tipo. El administrador de transacciones asume la responsabilidad de la comunicación entre todos los participantes de la transacción.
Mire la introducción anterior a las transacciones distribuidas, ¿es similar a la gestión de transacciones en 2pc? Sin embargo, 2PC es en realidad un método de implementación para un administrador de transacciones que cumple con la especificación XA para coordinar múltiples gerentes de recursos. He tenido varios artículos en 2pc y 3pc antes. En esos artículos, he introducido cómo el administrador de transacciones en transacciones distribuidas coordina la confirmación unificada o la reversión de múltiples transacciones. También presentaré en detalle el contenido relacionado con las transacciones distribuidas, incluidas, entre otros, transacciones globales, modelos DTP, transacciones flexibles, etc.
Pros y contras de JTA
La ventaja de JTA es que proporciona una solución de transacción distribuida y ácido estricto. Sin embargo, la gestión estándar de la transacción JTA no se usa comúnmente en el desarrollo diario porque tiene muchas deficiencias:
Complejo de implementación
Normalmente, la transacción de usuario de JTA debe obtenerse de JNDI. Esto significa que si usamos JTA, necesitamos usar JTA y JNDI.
JTA en sí es una API voluminosa.
Por lo general, JTA solo se puede usar en entornos de servidor de aplicaciones, por lo que el uso de JTA limitará la reutilización del código.
Resumir
Hay tres tipos de transacciones Java: transacción JDBC, transacción JTA (API de transacción Java) y transacción de contenedores. Entre ellos, el uso de operación de transacción de JDBC es relativamente simple y adecuado para manejar operaciones de la misma fuente de datos. Las transacciones JTA son relativamente complejas y pueden usarse para manejar las transacciones en múltiples bases de datos. Son una solución para transacciones distribuidas.
Permítanme hablar brevemente de eso aquí. Aunque las transacciones JTA son un conjunto de API proporcionadas por Java para transacciones distribuidas, diferentes plataformas J2EE tienen implementaciones diferentes y no son muy convenientes de usar. Por lo tanto, esta API más responsable generalmente no se usa en proyectos. Las soluciones de transacción distribuidas comúnmente utilizadas en la industria ahora incluyen garantía de mensajes asincrónicos, TCC, notificación de máximo esfuerzo, etc.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.