Il existe trois types de transactions Java: la transaction JDBC, la transaction JTA (API de transaction Java) et la transaction de conteneurs. Transactions de conteneurs communes telles que les transactions Spring. Les transactions de conteneurs sont principalement fournies par les serveurs d'application J2EE. La plupart des transactions de conteneurs sont effectuées en fonction de JTA. Il s'agit d'une implémentation d'API assez complexe basée sur JNDI. Par conséquent, cet article ne discutera pas des transactions de conteneurs pour le moment. Cet article introduit principalement deux transactions relativement basiques dans le développement J2EE: la transaction JDBC et la transaction JTA.
Transactions JDBC
Tous les comportements, y compris les transactions, de JDBC, sont basés sur une connexion et la gestion des transactions est effectuée via l'objet de connexion dans JDBC. Dans JDBC, les méthodes liées aux transactions couramment utilisées sont: SetAutoCommit, Commit, Rollback, etc.
Voici un simple code de transaction JDBC:
public void jdbctransfer () {java.sql.connection conn = null; essayez {conn = conn = driverManager.getConnection ("jdbc: oracle: mince: @host: 1521: sid", "username", "userpwd"); // Définir le commit automatique sur FALSE, // Si défini sur true, la base de données reconnaîtra chaque mise à jour de données comme une transaction et soumetra automatiquement Conn.SetAutoCommit (FALSE); STMT = Conn.CreateStatement (); // Réduisez le montant du compte A par 500 STMT.Execute ("/ Update T_Account set Montant = Montant - 500 Where Account_id = 'A'"); // Augmentez le montant du compte B de 500 STMT.ExECUTE ("/ Update T_Account Set Muct = Montant + 500 WHERE COUTE_ID = 'B'"); // Soumettre la transaction Conn.Commit (); // Commit transaction: l'opération en deux étapes du transfert réussit en même temps} catch (sqlexception sqle) {try {// une exception se produit, rollback () dans cette transaction conn.rollback (); // Rollback de transaction: l'opération en deux étapes du transfert révèle complètement STMT.Close (); conn.close (); } catch (exception ignore) {} sqle.printStackTrace (); }}Le code ci-dessus implémente une fonction de transfert simple, qui contrôle l'opération de transfert par le biais de transactions, soit soumettant ou retournant.
Avantages et inconvénients des transactions JDBC
JDBC fournit la prise en charge la plus élémentaire pour les opérations de transaction de base de données à l'aide de Java. Grâce aux transactions JDBC, nous pouvons mettre plusieurs instructions SQL dans la même transaction pour assurer leurs caractéristiques acides. Le principal avantage des transactions JDBC est que l'API est relativement simple, peut implémenter les opérations de transaction les plus basiques et que les performances sont relativement bonnes.
Cependant, les transactions JDBC ont une limitation: une transaction JDBC ne peut pas courir plusieurs bases de données! ! ! Par conséquent, si plusieurs opérations de base de données ou scénarios distribués sont impliqués, les transactions JDBC sont impuissantes.
Transactions JTA
Pourquoi JTA est nécessaire
Habituellement, les transactions JDBC peuvent résoudre des problèmes tels que la cohérence des données. Étant donné que son utilisation est relativement simple, de nombreuses personnes savent seulement qu'il existe des transactions JDBC sur les transactions en Java, ou que certaines personnes connaissent les transactions dans des cadres (comme Hibernate, Spring), etc. Cependant, puisque JDBC ne peut pas mettre en œuvre des transactions distribuées, et il y a de plus en plus de scénarios distribués aujourd'hui, les transactions JTA émergent.
Si vous ne rencontrez pas de scénarios que les transactions JDBC ne peuvent pas être résolues au travail, vous pouvez seulement dire que les projets que vous faites sont encore trop petits. Prenez l'exemple des sites Web de commerce électronique. Nous divisons généralement un site Web de commerce électronique horizontalement en modules de produits, des modules de commande, des modules de panier, des modules de message, des modules de paiement, etc. Ensuite, nous déployons différents modules sur différentes machines, et chaque module communique via des appels de service à distance (RPC) et d'autres méthodes. Fournir des services au monde extérieur avec un système distribué.
Un processus de paiement doit interagir avec plusieurs modules, chaque module est déployé dans une autre machine et les bases de données exploitées par chaque module sont incohérentes. À l'heure actuelle, JDBC ne peut pas être utilisé pour gérer les transactions. Regardons un morceau de code:
/ ** Traitement des commandes de paiement ** / @Transactional (rollbackfor = exception.class) public void completeOrder () {orderDao.update (); // Le service de commande met à jour localement le comptabilité de l'état de la commande.update (); // Appelez le service de compte Fund pour ajouter des points au compte de fonds POINTERVICE.Update (); // Appelez le service de points pour ajouter des points au compte de points Compte Compte comptowerService.insert (); // Appelez le service comptable pour écrire le système comptable du système de comptabilité d'origine MerchantNotifyService.Notify (); // appelle le service de notification marchande pour envoyer une notification de résultat de paiement au marchand}Le code ci-dessus est une opération de processus de paiement simple, dans laquelle cinq services sont appelés, qui sont tous appelés via RPC. Comment assurer la cohérence des transactions à l'aide de JDBC? J'ai ajouté l'annotation @transactionnelle à la méthode, mais en raison de l'utilisation d'un service distribué, la transaction ne peut pas atteindre l'effet de l'acide.
Les transactions JTA sont plus puissantes que les transactions JDBC. Une transaction JTA peut avoir plusieurs participants, tandis qu'une transaction JDBC est limitée à une seule connexion de base de données. Les composants de l'une des plates-formes Java suivantes peuvent participer à une transaction JTA: connexion JDBC, objet JDO PersisterManager, JMS Queue, JMS Topic, Enterprise JavaBeans (EJB) et un allocateur de ressources compilé avec la spécification d'architecture du connexion J2EE.
Définition de JTA
L'API de transaction Java (JTA) est une version Java Enterprise de l'interface du programme d'application. Dans l'environnement Java, il permet de terminer les transactions distribuées sur plusieurs ressources XA.
JTA et son compatriot Java Transaction Service (JTS; Java TransactionService), fournissent des services de transaction distribués pour la plate-forme J2EE. Cependant, JTA fournit uniquement une interface et ne fournit pas de mise en œuvre spécifique. Au lieu de cela, il est fourni par le fournisseur de serveurs J2EE en fonction de la spécification JTS. Il existe plusieurs implémentations JTA communes:
1. Implémentation JTA (JBOSS) fournie par J2EE Container
2. Implémentations indépendantes de JTA: telles que JOTM, Atomikos. Ces implémentations peuvent être utilisées dans des environnements qui n'utilisent pas de serveurs d'applications J2EE pour fournir des garanties de transaction distribuées. Comme les applications Tomcat, Jetty et Ordinary Java.
JTA fournit Java.Transaction.UserTransaction, qui définit les méthodes suivantes.
Ici, il convient de noter que les opérations JDBC ordinaires peuvent être directement converties en opérations JTA sans utiliser UserTransaction. JTA possède des exigences pour la source de données, la connexion et les ressources. Seules les classes conformes à la spécification XA et implémenter les interfaces pertinentes de la spécification XA peuvent participer aux transactions JTA. Concernant la spécification XA, veuillez consulter l'introduction pertinente dans un autre article de mon article. Ici, permettez-moi de mentionner que les bases de données courant actuelles prennent en charge les spécifications XA.
Pour utiliser les transactions JTA, vous avez besoin d'un pilote JDBC qui implémente les interfaces Javax.sql.xadatasource, javax.sql.xaconnection et javax.sql.xaresource. Un pilote qui implémente ces interfaces pourra participer aux transactions JTA. Un objet Xadatasource est une usine d'un objet Xaconnection. Xaconnection est une connexion JDBC qui participe aux transactions JTA.
Pour utiliser les transactions JTA, vous devez utiliser XadataSource pour générer la connexion de la base de données, et la connexion résultante est une connexion XA.
La différence entre la connexion XA (javax.sql.xaconnection) et la connexion non xa (java.sql.connection) est que XA peut participer aux transactions JTA et ne prend pas en charge les commits automatiques.
Exemple de code:
public void jtatransfer () {javax.transaction.UserTransaction tx = null; java.sql.connection conn = null; essayez {tx = (javax.transaction.userTransaction) context.lookup ("java: comp / usertransaction"); // Obtenez des transactions JTA, dans ce cas, le conteneur JBoss est géré par Javax.sql.Datasource ds = (javax.sql.datasource) context.lookup ("java: / xaoraceds"); // Obtenez le pool de connexion de la base de données, il doit y avoir une base de données et un pilote qui prend en charge XA qui prend en charge TX.Begin (); Conn = ds.getConnection (); // Définir le commit automatique sur FALSE, // Si défini sur true, la base de données reconnaîtra chaque mise à jour de données comme une transaction et soumetra automatiquement Conn.SetAutoCommit (FALSE); STMT = Conn.CreateStatement (); // Diminue le montant du compte A par 500 STMT.Execute ("/ Update T_Account Set Montant = Montant - 500 WHERE COUTE_ID = 'A'"); // Augmentez le montant du compte B de 500 STMT.ExECUTE ("/ Update T_Account Set Muct = Montant + 500 WHERE COUTE_ID = 'B'"); // Augmentez le montant du compte B de 500 STMT.ExECUTE ("/ Update T_Account Set Muct = Montant + 500 WHERE COUTE_ID = 'B'"); // Augmentez le montant du compte B de 500 STMT.ExECUTE ("/ Update T_Account Set Muct = Montant + 500 WHERE COUTE_ID = 'B'"); // commit la transaction tx.commit (); // Commit de transaction: l'opération en deux étapes du transfert réussit en même temps} catch (sqlexception sqle) {try {// Une exception se produit, rollback () dans cette transaction; // Rollback de transaction: l'opération en deux étapes du transfert est entièrement révoquée stmt.close (); conn.close (); } catch (exception ignore) {} sqle.printStackTrace (); }} L'exemple ci-dessus est une opération de transfert à l'aide de transactions JTA. Cette opération dépend relativement du conteneur J2EE et nécessite l'obtention de la transaction et de la connexion utilisateur via JNDI.
Transactions distribuées standard
Une transaction distribuée comprend un gestionnaire de transactions et un ou plusieurs gestionnaires de ressources. Un gestionnaire de ressources est un magasin de données persistant de tout type. Le gestionnaire de transactions assume la responsabilité de la communication entre tous les participants aux transactions.
Regardez l'introduction ci-dessus aux transactions distribuées, est-ce similaire à la gestion des transactions en 2pc? Cependant, 2PC est en fait une méthode d'implémentation pour un gestionnaire de transactions conforme à la spécification XA pour coordonner plusieurs gestionnaires de ressources. J'ai déjà eu plusieurs articles sur 2pc et 3pc auparavant. Dans ces articles, j'ai introduit comment le gestionnaire de transactions dans les transactions distribuées coordonne le commit unifié ou le retour de transactions multiples. Je présenterai également en détail le contenu lié aux transactions distribuées, y compris, mais sans s'y limiter, les transactions globales, les modèles DTP, les transactions flexibles, etc.
Pour les avantages et les inconvénients de JTA
L'avantage de JTA est qu'il fournit une solution de transaction distribuée et un acide strict. Cependant, la gestion des transactions JTA standard n'est pas couramment utilisée dans le développement quotidien car elle a de nombreuses lacunes:
Complexe d'implémentation
Normalement, JTA UserRansaction doit être obtenu auprès de JNDI. Cela signifie que si nous utilisons JTA, nous devons utiliser JTA et JNDI.
JTA lui-même est une API volumineuse.
Habituellement, JTA ne peut être utilisé que dans des environnements de serveurs d'applications, donc l'utilisation de JTA limitera la réutilisabilité du code.
Résumer
Il existe trois types de transactions Java: la transaction JDBC, la transaction JTA (API de transaction Java) et la transaction de conteneurs. Parmi eux, l'utilisation des opérations de transaction de JDBC est relativement simple et adaptée à la gestion des opérations de la même source de données. Les transactions JTA sont relativement complexes et peuvent être utilisées pour gérer les transactions dans plusieurs bases de données. Ils sont une solution pour les transactions distribuées.
Permettez-moi d'en parler brièvement ici. Bien que les transactions JTA soient un ensemble d'API fournies par Java pour les transactions distribuées, différentes plates-formes J2EE ont des implémentations différentes et ne sont pas très pratiques à utiliser. Par conséquent, cette API plus responsable n'est généralement pas utilisée dans les projets. Les solutions de transaction distribuées couramment utilisées dans l'industrie comprennent désormais l'assurance de messages asynchrones, le TCC, la notification d'effort maximum, etc.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.