Aperçu
La gestion des transactions est cruciale pour les applications d'entreprise, et elle peut garantir la cohérence des données même si des situations anormales se produisent.
Spring Framework fournit une abstraction cohérente pour la gestion des transactions, avec ses caractéristiques comme suit:
Fournir des modèles de programmation cohérents pour différentes API de transaction, tels que JTA (Java Transaction API), JDBC, Hibernate, JPA (Java Persistance API et JDO (Java Data Objectts)
Prend en charge la gestion déclarative des transactions, en particulier la gestion des transactions déclaratives basée sur les annotations, ce qui est simple et facile à utiliser
Fournit une API de gestion des transactions de programmation plus simple que les autres API de transaction telles que JTA
Intégration parfaite avec l'abstraction d'accès aux données de printemps
Méthode de gestion des transactions
Spring prend en charge deux méthodes: la gestion des transactions programmatiques et la gestion des transactions déclaratives.
La gestion des transactions programmatiques utilise TransactionTemplate ou utilise directement la plate-forme sous-jacenteTransactionManager. Pour la gestion des transactions programmatiques, Spring recommande d'utiliser TransactionTemplate.
La gestion des transactions déclaratives est construite sur AOP. Son essence consiste à intercepter la méthode avant et après, puis à créer ou à ajouter une transaction avant le début de la méthode cible. Après avoir exécuté la méthode cible, la transaction est soumise ou renvoyée en fonction de la situation d'exécution. Le plus grand avantage des transactions déclaratives est qu'ils n'ont pas besoin de gérer les transactions par programme, il n'est donc pas nécessaire de dopant le code de gestion des transactions dans le code de logique métier. Faites simplement des déclarations de règles de transaction pertinentes dans le fichier de configuration (ou via @Transactional Annotation) et vous pouvez appliquer des règles de transaction à la logique métier.
De toute évidence, la gestion des transactions déclaratives est meilleure que la gestion des transactions programmatiques, qui est exactement la méthode de développement non invasive préconisée par Spring. La gestion des transactions déclaratives maintient le code commercial sans contamination. Un objet POJO normal peut obtenir un support de transaction complet en ajoutant des annotations. Par rapport aux transactions de programmation, le seul inconvénient des transactions déclaratives est que la meilleure granularité de ce dernier ne peut agir qu'au niveau de la méthode et ne peut pas être réalisée car une transaction programmatique peut agir au niveau du bloc de code. Cependant, même avec une telle exigence, il existe de nombreuses solutions de contournement, telles que les blocs de code qui nécessitent une gestion des transactions peuvent être traités indépendamment, etc.
Il existe également deux méthodes couramment utilisées pour la gestion des transactions déclaratives. L'un est le fichier de configuration XML basé sur les espaces de noms TX et AOP, et l'autre est basé sur l'annotation @transactionnelle. De toute évidence, la méthode basée sur l'annotation est plus simple et plus facile à utiliser et plus rafraîchissante.
Commit automatique (AutoCommit) et s'il faut soumettre automatiquement lorsque la connexion est fermée
Soumission automatique
Par défaut, la base de données est en mode de soumission automatique. Chaque instruction est dans une transaction distincte. Lorsque l'exécution de cette déclaration est terminée, si l'exécution est réussie, la transaction est implicitement soumise.
Si l'exécution échoue, la transaction est implicitement en arrière.
Pour la gestion normale des transactions, un ensemble d'opérations connexes est dans une transaction, de sorte que le mode de validation automatique de la base de données doit être désactivé. Cependant, nous n'avons pas à nous soucier de cela, Spring définira la fonction de validation automatique de la connexion sous-jacente à FALSE.
org / springframework / jdbc / dataSource / dataSourcetransactionManager.java
// Passez à un engagement manuel si nécessaire. Ceci est très coûteux dans certains pilotes JDBC, //, nous ne voulons donc pas le faire inutilement (par exemple si nous avons explicitement // configuré le pool de connexion pour le définir déjà) .i (con.getAutoCommit ()) {txObject.SetMustreAutoCommit (true); if (logger.isdebugeNabled ()) {logger.debug ("Switching JDBC Connection [" + Con + "] To Manual Commit"); } con.setAutoCommit (false);}Certains pools de connexion de données fournissent des paramètres pour désactiver les commits de transaction automatique, qui sont les mieux désactivés lors de la configuration du pool de connexion. Cependant, C3P0 ne fournit pas cette fonctionnalité et ne peut compter que sur le ressort pour le définir.
Étant donné que la spécification JDBC stipule que lorsque l'objet de connexion est établi, il doit être en mode de validation automatique, qui est la valeur par défaut entre les SGBD, et la validation automatique doit être explicitement désactivée si nécessaire. C3P0 respecte cette spécification et permet au code client de définir explicitement le mode de soumission requis.
S'il faut se soumettre automatiquement lorsque la connexion est fermée
Lorsqu'une connexion est fermée, qu'est-ce qui devrait être géré s'il y a une transaction non engagée? La spécification JDBC ne mentionne pas que la stratégie par défaut de C3P0 consiste à annuler des transactions non engagées. C'est la bonne stratégie, mais il n'y a pas d'accord entre les fournisseurs de pilotes JDBC sur cette question.
La propriété AutoCommitOnClose de C3P0 est fausse par défaut, il n'est donc pas nécessaire de ne pas le déplacer. Ou vous pouvez explicitement définir cette propriété sur FALSE, ce qui sera plus clair.
Configuration de gestion des transactions déclaratives basées sur l'annotation
Spring-Servlet.xml
<! - Prise en charge des transactions -> <! - PlatformTransactionMNager -> <bean id = "txManager"> <propriété name = "dataSource" ref = "dataSource" /> </ank> <! - Activer la prise en charge de l'annotation des transactions -> <tx: annotation-insived transaction-manager = "txmanager" />
Ajoutez également l'espace de noms TX dans Spring-Servlet.xml
... xmlns: tx = "http://www.springframework.org/schema/tx" xmlns: aop = "http://www.springframework.org/schema/aop" xsi: schemalation = "... http: //www.springframeworkwork.orma/tp: //www. http://www.springframework.org/schema/tx/spring-tx.xsd ...
MyBatis participe automatiquement à la gestion des transactions Spring sans configuration supplémentaire. Tant que la source de données référencée par org.mybatis.spring.sqlSessionFactoryBean est conforme à la source de données référencée par DataSourcetransactionManager, sinon la gestion des transactions ne fonctionnera pas.
De plus, vous devez télécharger le package de dépendance AOPALLIVIE.JAR et le mettre dans le répertoire Web-inf / lib. Sinon, une exception sera signalée lorsque le printemps sera initialisé
java.lang.noclassdeffounderror: org / aopalliance / intercept / méthode interceptor
Caractéristiques de transaction de printemps
Toutes les classes de politiques de gestion des transactions à Spring sont héritées de l'org.springframework.transaction.platformTransactionManager
Interface publique PlatformTransactionManager {TransactionStatus GetTransaction (TransactionDefinition Définition) Throws TransactionException; VOID COMMING (TransactionStatus Status) lève TransactionException; Void Rollback (TransactionStatus Status) lève TransactionException;}L'interface TransactionDefinition définit les caractéristiques suivantes:
Niveau d'isolement des transactions
Le niveau d'isolement fait référence au degré d'isolement entre plusieurs transactions simultanées. Cinq constantes représentant les niveaux d'isolement sont définies dans l'interface de la définition de la transaction:
TransactionDefinition.isolation_default: Il s'agit de la valeur par défaut, indiquant le niveau d'isolement par défaut utilisé pour la base de données sous-jacente. Pour la plupart des bases de données, cette valeur est généralement TransactionDefinition.isolation_read_Committed.
TransactionDefinition.isolation_Read_UnCitmit: Ce niveau d'isolement indique qu'une transaction peut lire les données modifiées par une autre transaction mais n'a pas encore été commise. Ce niveau n'empêche pas la lecture sale, la lecture répétitive et la lecture des fantômes, donc ce niveau d'isolement est rarement utilisé. Par exemple, PostgreSQL n'a pas réellement ce niveau.
TransactionDefinition.isolation_Read_Committed: Ce niveau d'isolement signifie qu'une seule transaction ne peut lire que des données qui ont été commises par une autre transaction. Ce niveau empêche la lecture sale, qui est également la valeur recommandée dans la plupart des cas.
TransactionDefinition.isolation_repeatable_read: Ce niveau d'isolement indique qu'une transaction peut exécuter une requête plusieurs fois tout au long du processus, et les enregistrements renvoyés sont les mêmes à chaque fois. Ce niveau empêche les lectures sales et non répétibles.
TransactionDefinition.isolation_Serializable: toutes les transactions sont exécutées une par une en séquence, afin qu'il n'y ait aucune possibilité d'interférence entre les transactions, c'est-à-dire ce niveau peut empêcher la lecture sale, la lecture non répétée et la lecture fantôme. Mais cela affectera sérieusement les performances du programme. Ce niveau n'est généralement pas utilisé.
Comportement de communication des transactions
Le comportement soi-disant de propagation des transactions fait référence à cela si un contexte de transaction existe déjà avant le démarrage de la transaction actuelle, plusieurs options peuvent spécifier le comportement d'exécution d'une méthode transactionnelle. La définition de la définition de la définition comprend les constantes suivantes représentant le comportement de propagation:
TransactionDefinition.Propagation_Required: Si une transaction est actuellement présente, rejoignez la transaction; S'il n'y a actuellement aucune transaction, créez une nouvelle transaction. Ceci est la valeur par défaut.
TransactionDefinition.Propagation_Requires_New: Crée une nouvelle transaction, et si la transaction existe actuellement, la transaction actuelle sera suspendue.
TransactionDefinition.Propagation_Supports: Rejoignez la transaction en cas de transaction actuellement; S'il n'y a actuellement aucune transaction, il continue de s'exécuter de manière non transactionnelle.
TransactionDefinition.propagation_NOT_SUPPORTED: Exécute de manière non transactionnelle, et si une transaction existe actuellement, la transaction actuelle sera suspendue.
TransactionDefinition.Propagation_Never: s'exécute de manière non transactionnelle, lance une exception si une transaction est actuellement présente.
TransactionDefinition.Propagation_Mandatory: Rejoignez la transaction s'il existe actuellement une transaction; S'il n'y a actuellement aucune transaction, une exception est lancée.
TransactionDefinition.Propagation_neSéed: Si une transaction est actuellement présente, une transaction est créée pour s'exécuter en tant que transaction imbriquée de la transaction actuelle; S'il n'y a pas de transaction, la valeur est équivalente à TransactionDefinition.Propagation_Required.
Timeout de transaction
Le délai d'expiration de la transaction se réfère au temps maximum autorisé par une transaction. Si le délai est dépassé mais que la transaction n'est pas terminée, la transaction sera automatiquement annulée. Dans TransactionDefinition, le délai d'expiration est représenté par la valeur d'Int, et son unité est en seconde.
Le paramètre par défaut est la valeur de délai d'expiration du système de transaction sous-jacent. Si le système de transaction de base de données sous-jacent ne définit pas la valeur de délai d'expiration, il n'en est pas et il n'y a pas de limite de délai d'attente.
Attributs en lecture seule de la transaction
Les transactions en lecture seule sont utilisées dans des situations où le code client est en lecture seule mais ne modifie pas les données. Les transactions en lecture seule sont utilisées dans l'optimisation dans des scénarios spécifiques, comme lors de l'utilisation d'Hibernate.
La valeur par défaut est la lecture et l'écriture de transactions.
Règles de recul des transactions de printemps
La façon recommandée de demander au Spring Transaction Manager de faire reculer une transaction consiste à lancer une exception dans le contexte de la transaction actuelle. Le Spring Transaction Manager attire toutes les exceptions non gérées, puis décide de faire reculer la transaction qui lance l'exception en fonction des règles.
Par défaut, Spring ne fera en arrière la transaction que si l'exception lancée est une exception non contrôlée, c'est-à-dire que l'exception lancée est une sous-classe de RuntimeException (les erreurs entraîneront également un recul des transactions), tandis que le lancement d'une exception vérifiée ne provoquera pas le retour de transaction.
Il est possible de configurer explicitement la transaction à reculer lorsque ces exceptions sont lancées, y compris les exceptions vérifiées. Il est également possible de définir clairement les transactions qui ne reculent pas lorsque les exceptions sont lancées.
Vous pouvez également utiliser par programme la méthode SetRollBackOnly () pour indiquer qu'une transaction doit être annulée. La seule chose que vous pouvez faire après avoir appelé setRollBackOnly () est le Rollback.
@Transactional Annotation
@Transactional Properties
| propriété | taper | décrire |
|---|---|---|
| valeur | Chaîne | Descripteur de qualification facultatif, spécifiant le gestionnaire de transactions à utiliser |
| propagation | Énume: propagation | Paramètres de comportement de propagation des transactions facultatifs |
| isolement | Énume: isolement | Paramètres de niveau d'isolement de transaction facultatif |
| lire en lecture | booléen | Lire et écrire ou lire la transaction seule, lire et écrire par défaut |
| temps mort | int (en secondes granularité) | Paramètre de délai d'expiration des transactions |
| RollbackFor | Le tableau d'objets de classe doit être hérité de | Tableau de classes d'exception qui provoquent un recul des transactions |
| RollbackForClassName | La gamme de noms de classe doit être héritée de | Tableau de noms de classes d'exception qui provoquent un recul des transactions |
| Norollbackfor | Le tableau d'objets de classe doit être hérité de | Un tableau de classe d'exception qui ne provoque pas de recul des transactions |
| Norollbackforclassname | La gamme de noms de classe doit être héritée de | Un tableau de noms de classes d'exception qui ne provoqueront pas de recul des transactions |
usage
@Transactional peut agir sur les interfaces, les méthodes d'interface, les classes et les méthodes de classe. Lorsque vous agissez sur une classe, toutes les méthodes publiques de la classe auront des propriétés de transaction de ce type. Dans le même temps, nous pouvons également utiliser cette annotation au niveau de la méthode pour remplacer la définition au niveau de la classe.
Bien que l'annotation @transactionnelle puisse être appliquée aux interfaces, aux méthodes d'interface, aux classes et aux méthodes de classe, Spring recommande de ne pas utiliser cette annotation sur les interfaces ou les méthodes d'interface, car cela ne prendra effet que lorsque vous utilisez un proxy basé sur l'interface. De plus, l'annotation @transactionnelle ne doit être appliquée qu'à la méthode publique, qui est déterminée par la nature du printemps AOP. Si vous utilisez l'annotation @transactionnelle sur des méthodes de visibilité protégées, privées ou par défaut, cela sera ignoré et aucune exception ne sera lancée.
Par défaut, seuls les appels de la méthode de l'extérieur seront capturés par le proxy AOP, c'est-à-dire que l'appel d'autres méthodes à l'intérieur de cette classe à l'intérieur de la classe ne provoquera pas de comportement de transaction, même si la méthode appelée est modifiée à l'aide de l'annotation @transactionnelle.
@Transactional (readonly = true) public class defaultfooservice implémente Fooservice {public foo getfoo (string fooname) {// faire quelque chose} // ces paramètres ont la priorité pour cette méthode // l'attribut d'annotation sur la méthode remplacera le même attribut sur l'annotation de classe @Transactional (readonly = false, propagation = propagation.require public) UpdateFoo (foo foo) {// faire quelque chose}}Résumer
Ce qui précède est tout le contenu de l'interprétation par cet article de l'utilisation de l'annotation @transactionnelle au printemps, et j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!