Préface
L'adresse de téléchargement de l'exemple de code pour cet article (entièrement exécuté, y compris les fichiers SQL, veuillez modifier la configuration de la base de données après le téléchargement): cliquez ici pour télécharger
Plusieurs opérations de base de données sont contrôlées dans leur ensemble et réussissent ou échouent ensemble.
Atomicité: fait référence à une transaction étant une unité de travail inséparable et des opérations dans une transaction se produisent ou aucune ne se produit.
Cohérence: signifie que l'intégrité des données avant et après une transaction doit être cohérente.
Isolement: Lorsque plusieurs utilisateurs accèdent simultanément à la base de données, les transactions d'un utilisateur ne peuvent pas être interférées par les transactions d'autres utilisateurs, et les données entre plusieurs transactions simultanées doivent être isolées les unes des autres.
Persistance: une fois la transaction engagée, ses modifications apportées aux données de la base de données sont permanentes et l'échec de la base de données instantanée ne devrait avoir aucun impact sur celle-ci.
--PlatForm TransactionManager Transaction Manager (commit, Rollback Transactions)
Spring fournit différentes implémentations d'interface TransactionManager de plate-forme pour différents cadres de persistance. comme:
Utilisation de DataSourcetransactionManager lors de la persistance des données à l'aide de Spring JDBC ou Ibatis
Utilisez HiberNateTransActionManager lorsque vous utilisez HiberNate3.0 pour des données persistantes
--TransactionDefinition Transaction Definition Informations (isolement, propagation, délai d'expiration, lecture seule)
Dirty Reading: Une transaction lit des données qui ont été réécrites par une autre transaction mais qui n'ont pas encore été soumises. Si ces données sont annulées, les données de lecture ne sont pas valides.
Aucune lecture répétitive: dans la même transaction, les résultats renvoyés en lisant les mêmes données sont différents.
Lecture fantastique: après qu'une transaction lit plusieurs lignes d'enregistrements, une autre transaction insère certains enregistrements et la lecture fantastique se produit. Dans la dernière requête, la première transaction trouvera des enregistrements qui n'étaient pas à l'origine disponibles.
Niveau d'isolement des transactions: (cinq types)
Parmi eux, MySQL utilise le niveau d'isolement répétable_read par défaut; Oracle utilise le niveau d'isolement Read_Commilute par défaut
Comportement de communication des transactions: (sept types)
- TRANSACTACSSTATUS TRANSACTION STATION SPÉCIAL
un. Gestion des transactions de programmation (basée sur le contrôle de la programmation Java, rarement utilisée) - voir le package Demo1
Utilisez TransactionTemplate pour encapsuler plusieurs opérations DAO
* b. Gestion des transactions déclaratives (contrôle de configuration AOP basé sur Spring)
- Basé sur TransactionProxyFactoryBean. (Rarement utilisé) - voir le package Demo2
Il est nécessaire de configurer une transactionproxyfactoryBean pour chaque classe qui subit une gestion des transactions pour améliorer.
-Pack sur la configuration XML (utilisée fréquemment) - voir le package Demo3
Une fois configuré, rien ne doit être ajouté à la classe.
Si l'action est un objet cible pour saisir la transaction, vous devez ajouter l'attribut proxy-target-class = "true" à l'élément <aop: config>. La raison en est d'informer le cadre Spring pour utiliser la technologie CGLIB pour générer des classes d'action avec des fonctions de gestion des transactions.
-En basé sur les annotations (configuration simple, souvent utilisée) - voir le package Demo4
Activer la configuration d'annotation de transaction dans ApplicationContext.xml. (Dans ApplicationContext.xml, définissez simplement le bean et ajoutez les éléments suivants)
<bean id = "txManager"> <propriété name = "sessionfactory"> </ propriété> <tx: transaction-manager de transaction annotation = "txManager" />
Utilisez @Transactional dans la classe de composants cible, qui peut être définie avant la classe ou avant la méthode.
--Programmation
/ ** * @Description: Interface de couche DAO du cas de transfert * * / interface publique AccountDao {/ ** * @param out *: Compte de transfert * @param money *: Montant de transfert * / public void outmoney (String Out, double monnaie); / ** * * @param dans *: Compte de transfert * @param money *: Montant de transfert * / public void inmoney (chaîne en, double monnaie); } / ** * @Description: la classe d'implémentation de la couche DAO du cas de transfert * / classe publique AccountDaoimpl étend JDBCDAOSUPPORT implémente AccountDao {/ ** * @param Out *: Transfert Account * @param Money *: Transfer Month * / @Override Public Void OutMoney (String Out, Double Money) {String Sql = "Update Compte Set mononey = Money-? this.getJDBCTemplate (). Update (SQL, Money, Out); } / ** * @param dans *: Compte de transfert * @param Money *: Montant de transfert * / @Override public void inmoney (String in, double money) {String sql = "Mise à jour le set de compte Money = Money +? Where name =?"; this.getJDBCTemplate (). Update (SQL, Money, IN); }} / ** * @Description: Interface commerciale du boîtier de transfert * * / Interface publique Compte Natservice {/ ** * @param Out: Transfer Out * @param dans: Compte de transfert * @param Money: Montant de transfert * / Transfert public public (chaîne out, chaîne en, double monnaie); } / ** * @Description: Classe d'implémentation de la couche commerciale du cas de transfert * / classe publique AccountServiceIMPl implémente le comptabilité {// dao Private AccountDao AccountDao; // Modèle d'injection de gestion des transactions Private TransactionTemplate TransactionTemplate; / ** * @param out *: transfert out * @param dans *: le compte de transfert * @param money *: Montant de transfert * / @Override public void transfert (chaîne finale out, chaîne finale, argent double final) {// Si une exception se produit pendant le processus, l'opération précédente peut être terminée. Si ce dernier ne le peut pas, le transfert est réussi mais le transfert n'est pas reçu. // accountdao.outmoney (out, argent); // int i = 1/0; // accountdao.inmoney (en, monnaie); TransactionTemplate.Execute (new TransactionCallbackWithoutreSult () {@Override Protected void DoIntransactionWithoutreSult (transactionStatus TransactionStatus) {Contratdao.outmoney (Out, Money); // int i = 1/0; // transaction Control, qui est, une exception se produit, et dans ce segment est exécutée sur Invalid AccountDa.in. }}); } public void setAccountDao (accountdao accountdao) {this.accountdao = accountdao; } public void setTransActionTemplate (transactionTemplate TransactionTemplate) {this.transactionTemplate = transactionTemplate; }}applicationContext1.xml
<! - Introduire des fichiers de propriétés externes -> <Context: propriété-placeholder location = "classPath: jdbc.properties" /> <! - Configurer le pool de connexion C3P0 -> <bean id = "dataSource"> <propriété name = "driverclass" value = "$ {jdbc. Value = "$ {jdbc.url}" /> <propriété name = "user" value = "$ {jdbc.Username}" /> <propriété name = "mot de passe" value = "$ {jdbc.password}" /> </ bean> <! - Configure la classe de la couche commerciale -> <bean id = "accounton"> <propriété Nom = "AccountDao" reflé <! - Injecter le modèle pour la gestion des transactions -> <propriété name = "transactionTemplate" ref = "transactionTemplate" /> </Ean> <! - Configurer la classe DAO (Simplified, JDBCTemplate sera automatique <! - <bean id = "jdbctemplate"> <propriété name = "dataSource" ref = "dataSource" /> </ bean> <bean id = "accountdao"> <propriété name = "jdbcTemplate" ref = "jdbcTemplate" /> </ bean> -> <! - =============================================================================================================================. ==============================================================================================================================. ==============================================================================================================================. ==============================================================================================================================. Configurer le modèle de gestion des transactions: les classes fournies par Spring pour simplifier le code de gestion des transactions -> <bean id = "TransactionTemplate"> <propriété name = "TransactionManager" ref = "TransactionManager" /> </EAN>test:
@Runwith (springjunit4classrunner.class) @contextConfiguration ("classpath: applicationContext1.xml") public class transactionTest {@Resource (name = "accountervice") Private AccountService AccountService; @Test Public void Demo1 () {accountervice.transfer ("aaa", "bbb", 200d); }}- Une méthode basée sur TransactionProxyFactoryBean
classe publique AccountServiceIMPl implémente le comptabilité {// dao private accountdao actedao; / ** * @param out *: transfert out * @param dans *: Compte de transfert * @param money *: Montant de transfert * / @Override public void transfert (chaîne out, string in, double money) {accountdao.outmoney (out, argent); // int i = 1/0; accountdao.inmoney (in, argent); } public void setAccountDao (accountdao accountdao) {this.accountdao = accountdao; }}applicationContext2.xml
<! - Introduire des fichiers de propriétés externes -> <Context: propriété-placeholder location = "classPath: jdbc.properties" /> <! - Configurer le pool de connexion C3P0 -> <bean id = "dataSource"> <propriété name = "driverclass" value = "$ {jdbc. Value = "$ {jdbc.url}" /> <propriété name = "user" value = "$ {jdbc.Username}" /> <propriété name = "mot de passe" value = "$ {jdbc.password}" /> </ bean> <! - Configure la classe de la couche commerciale -> <bean id = "accounton"> <propriété Nom = "AccountDao" reflé </EAN> <! - Configurez la classe DAO (simplifiée, configure automatiquement JDBCTemplate) -> <bean id = "accountdao"> <propriété name = "dataSource" ref = "dataSource" /> </ank> <! - =======================================================================================================================. =======================================================================================================================. =======================================================================================================================. =======================================================================================================================. -> <! - Configurer le gestionnaire de transactions -> <bean id = "TransactionManager"> <propriété name = "dataSource" ref = "dataSource" /> </Ean> <! - Configurez le proxy pour le calque commercial -> <bean id = "AccountServiceProxy"> <! name = "TransactionManager" ref = "TransactionManager"> </ propriété> <! - Inject Properties de transaction -> <propriété name = "TransactionAttributes"> <props> <! - Format de Prop: * Propagation: Comportement de propagation des transactions * Isotation: transaction Isolation Niveau * Readonly: Read-Only * -exception: quelles exceptions transactions * + exception: quelles exceptions ne font pas de transaction - key = "transfert"> propagation_required </prop> <! - <prop key = "transfert"> propagation_required, readonly </prop> -> <! - <prop key = "transfert"> propagation_required, readonly </prop> -> <! - <prop key = "transfert"> propagation_requered, + java.lang.arithMeticexception </props> </ props> </ propriété> </ban>test:
@Runwith (springjunit4classrunner.class) @contextconfiguration ("classpath: applicationContex.xml") Classe publique TransactionTest {/ ** * Assurez-vous d'injecter la classe de proxy: car la classe proxy effectue des opérations améliorées * / // @Resource (nom = compte pourvivice ") @Resource (nom =" AccountsViceSy ") Private") @Resource (Name = "AccountsWervice") Privé ") Accador-service; @Test Public void Demo1 () {accountervice.transfer ("aaa", "bbb", 200d); }}- basé sur la configuration XML
classe publique AccountServiceIMPl implémente le comptabilité {// dao private accountdao actedao; / ** * @param out *: transfert out * @param dans *: Compte de transfert * @param money *: Montant de transfert * / @Override public void transfert (chaîne out, string in, double money) {accountdao.outmoney (out, argent); // int i = 1/0; accountdao.inmoney (in, argent); } public void setAccountDao (accountdao accountdao) {this.accountdao = accountdao; }}applicationContex.xml
<! - Introduire des fichiers de propriétés externes -> <Context: propriété-placeholder location = "classPath: jdbc.properties" /> <! - Configurer le pool de connexion C3P0 -> <bean id = "dataSource"> <propriété name = "driverclass" value = "$ {jdbc. Value = "$ {jdbc.url}" /> <propriété name = "user" value = "$ {jdbc.Username}" /> <propriété name = "mot de passe" value = "$ {jdbc.password}" /> </ bean> <! - Configure la classe de la couche commerciale -> <bean id = "accounton"> <propriété Nom = "AccountDao" reflé </EAN> <! - Configurez la classe DAO (simplifiée, configure automatiquement JDBCTemplate) -> <bean id = "accountdao"> <propriété name = "dataSource" ref = "dataSource" /> </ank> <! - ========================================================================. ==========================================================================. ==========================================================================. ==========================================================================. ==========================================================================. ==========================================================================. ==========================================================================. ==========================================================================. : Comportement de propagation des transactions Isolation: niveau d'isolement des transactions en lecture seule: en lecture seule-retour pour: quelles exceptions se sont produites sans rollback-pour: quelles exceptions se sont produites non pas le temps mort: les informations d'expiration -> <Tx: Method Name = "Transfer" propagation = "required" /> </ tx: attributes> </ tx: conseils> <! - Section de configuration -> <aop: configriation> <! <aop: Pointcut Expression = "EXECUTION (* com.zs.spring.demo3.accountService +. * (..))" id = "Pointcut1" /> <! - Section de configuration -> <aop: Advisor conseils-ref = "txadvice" Pointcut-ref = "Pointcut1" /> </ aop: config>test:
/ ** * @Description: la méthode de gestion des transactions déclaratives de Spring deux: Configuration XML basée sur AspectJ * / @runwith (SpringJunit4ClassRunner.class) @ContextConfiguration ("ClassPath: ApplicationContext3.xml") Classe publique TransactionTest {/ ** * doit injecter la classe Proxy: Parce que la classe Proxy effectue des opérations améliorées * / @Resource (NOM-NOM = NOS "Accountervice") Private Accountvice AccountService; @Test Public void Demo1 () {accountervice.transfer ("aaa", "bbb", 200d); }}- basé sur l'annotation
/ ** * @Transactional Propagation: Transaction Propagation Comportement Isolation: Transaction Niveau d'isolement ReadOnly: Read-Only * RollbackFor: Quelles exceptions se sont produites NorollbackFor: Quelles exceptions se sont produites et non rollback * RollbackForClassname Rollback selon l'isolation des exceptions * / @Transactional (propagation = False) Classe. implémente AccountService {// DAO Injecting Transfer Private AccountDao AccountDao; / ** * @param out *: Compte de transfert * @param dans *: Compte de transfert * @param Money *: Montant de transfert * / @Override public void transfert (String Out, String in, Double Money) {accountdao.outmoney (out, monnaie); // int i = 1/0; accountdao.inmoney (in, argent); } public void setAccountDao (accountdao accountdao) {this.accountdao = accountdao; }}applicationContext4.xml
<! - Introduire des fichiers de propriétés externes -> <Context: propriété-placeholder location = "classPath: jdbc.properties" /> <! - Configurer le pool de connexion C3P0 -> <bean id = "dataSource"> <propriété name = "driverclass" value = "$ {jdbc. Value = "$ {jdbc.url}" /> <propriété name = "user" value = "$ {jdbc.Username}" /> <propriété name = "mot de passe" value = "$ {jdbc.password}" /> </ bean> <! - Configure la classe de la couche commerciale -> <bean id = "accounton"> <propriété Nom = "AccountDao" reflé </EAN> <! - Configurez la classe DAO (simplifiée, configure automatiquement JDBCTemplate) -> <bean id = "accountdao"> <propriété name = "dataSource" ref = "dataSource" /> </ank> <! - =======================================================================================================================. =======================================================================================================================. =======================================================================================================================. =======================================================================================================================. Configurer le gestionnaire de transaction -> <bean id = "TransactionManager"> <propriété name = "dataSource" ref = "dataSource" /> </ank> <! - Activez la transaction d'annotation -> <tx: transaction-manager) dirigée par l'annotation = "TransactionManager" />test:
@Runwith (springjunit4classrunner.class) @contextConfiguration ("classpath: applicationContex.xml") Classe publique TransactionTest {/ ** * Assurez-vous d'injecter la classe proxy: parce que la classe proxy effectue des opérations améliorées * / @Resource (name = "Accountvice") PROXT-COMPTESSERVICE COMPTESTERS NIFFICE; @Test Public void Demo1 () {accountervice.transfer ("aaa", "bbb", 200d); }}Pour un code spécifique et un projet de référence de fichier de base de données Code complet:
http://xiazai.vevb.com/201805/yuanma/spring-transaction_jb51.rar
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.