Gestion des transactions déclaratives de printemps

L'approche de gestion déclarative des transactions vous permet de gérer la transaction à l'aide de la configuration au lieu du codage en dur dans votre code source. Cela signifie que vous pouvez séparer la gestion des transactions du code métier. Vous n'utilisez que des annotations ou une configuration XML pour gérer les transactions. La configuration du bean spécifiera les méthodes transactionnelles. Voici les étapes associées à la transaction déclarative -

  • Nous utilisons la balise <tx: advice />, qui crée un avis de gestion des transactions et en même temps nous définissons un pointcut qui correspond à toutes les méthodes que nous souhaitons effectuer des transactions et référencons les conseils transactionnels.

  • Si un nom de méthode a été inclus dans la configuration transactionnelle, le conseil créé commencera la transaction avant d'appeler la méthode.

  • La méthode cible sera exécutée dans un bloc try / catch .

  • Si la méthode se termine normalement, l'avis AOP valide la transaction, sinon il effectue une annulation.

Voyons comment les étapes mentionnées ci-dessus fonctionnent mais avant de commencer, il est important d'avoir au moins deux tables de base de données sur lesquelles nous pouvons effectuer diverses opérations CRUD à l'aide de transactions. Prenons unStudent table, qui peut être créée dans la base de données MySQL TEST avec le DDL suivant -

CREATE TABLE Student(
   ID   INT NOT NULL AUTO_INCREMENT,
   NAME VARCHAR(20) NOT NULL,
   AGE  INT NOT NULL,
   PRIMARY KEY (ID)
);

La deuxième table est Marksdans lequel nous maintiendrons les notes des étudiants en fonction des années. IciSID est la clé étrangère de la table Student.

CREATE TABLE Marks(
   SID INT NOT NULL,
   MARKS  INT NOT NULL,
   YEAR   INT NOT NULL
);

Maintenant, écrivons notre application Spring JDBC qui implémentera des opérations simples sur les tables Student et Marks. Laissez-nous mettre en place un IDE Eclipse fonctionnel et suivez les étapes suivantes pour créer une application Spring -

Étape La description
1 Créez un projet avec un nom SpringExample et créez un package com.tutorialspoint sous lesrc dossier dans le projet créé.
2 Ajoutez les bibliothèques Spring requises à l'aide de l' option Ajouter des JAR externes comme expliqué dans le chapitre Exemple de Spring Hello World .
3 Ajoutez d'autres bibliothèques requises mysql-connector-java.jar , aopalliance-xyjar , org.springframework.jdbc.jar et org.springframework.transaction.jar dans le projet. Vous pouvez télécharger les bibliothèques requises si vous ne les avez pas déjà.
4 Créez l'interface DAO StudentDAO et répertoriez toutes les méthodes requises. Bien que ce ne soit pas obligatoire et que vous puissiez directement écrire la classe StudentJDBCTemplate , mais comme bonne pratique, faisons-le.
5 Créez d'autres classes Java requises StudentMarks , StudentMarksMapper , StudentJDBCTemplate et MainApp sous le package com.tutorialspoint . Vous pouvez créer le reste des classes POJO si nécessaire.
6 Assurez-vous que vous avez déjà créé Student et Markstables dans la base de données TEST. Assurez-vous également que votre serveur MySQL fonctionne correctement et que vous disposez d'un accès en lecture / écriture à la base de données en utilisant le nom d'utilisateur et le mot de passe donnés.
sept Créez le fichier de configuration Beans Beans.xml sous lesrc dossier.
8 La dernière étape consiste à créer le contenu de tous les fichiers Java et le fichier de configuration Bean et à exécuter l'application comme expliqué ci-dessous.

Voici le contenu du fichier d'interface de l'objet d'accès aux données StudentDAO.java

package com.tutorialspoint;

import java.util.List;
import javax.sql.DataSource;

public interface StudentDAO {
   /** 
      * This is the method to be used to initialize
      * database resources ie. connection.
   */
   public void setDataSource(DataSource ds);
   
   /** 
      * This is the method to be used to create
      * a record in the Student and Marks tables.
   */
   public void create(String name, Integer age, Integer marks, Integer year);
   
   /** 
      * This is the method to be used to list down
      * all the records from the Student and Marks tables.
   */
   public List<StudentMarks> listStudents();
}

Voici le contenu de la StudentMarks.java fichier

package com.tutorialspoint;

public class StudentMarks {
   private Integer age;
   private String name;
   private Integer id;
   private Integer marks;
   private Integer year;
   private Integer sid;

   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
   public void setId(Integer id) {
      this.id = id;
   }
   public Integer getId() {
      return id;
   }
   public void setMarks(Integer marks) {
      this.marks = marks;
   }
   public Integer getMarks() {
      return marks;
   }
   public void setYear(Integer year) {
      this.year = year;
   }
   public Integer getYear() {
      return year;
   }
   public void setSid(Integer sid) {
      this.sid = sid;
   }
   public Integer getSid() {
      return sid;
   }
}

Voici le contenu de la StudentMarksMapper.java fichier

package com.tutorialspoint;

import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

public class StudentMarksMapper implements RowMapper<StudentMarks> {
   public StudentMarks mapRow(ResultSet rs, int rowNum) throws SQLException {
      StudentMarks studentMarks = new StudentMarks();
      studentMarks.setId(rs.getInt("id"));
      studentMarks.setName(rs.getString("name"));
      studentMarks.setAge(rs.getInt("age"));
      studentMarks.setSid(rs.getInt("sid"));
      studentMarks.setMarks(rs.getInt("marks"));
      studentMarks.setYear(rs.getInt("year"));

      return studentMarks;
   }
}

Voici le fichier de classe d'implémentation StudentJDBCTemplate.java pour l'interface DAO StudentDAO définie

package com.tutorialspoint;

import java.util.List;
import javax.sql.DataSource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;

public class StudentJDBCTemplate implements StudentDAO {
   private JdbcTemplate jdbcTemplateObject;

   public void setDataSource(DataSource dataSource) {
      this.jdbcTemplateObject = new JdbcTemplate(dataSource);
   }
   public void create(String name, Integer age, Integer marks, Integer year){
      try {
         String SQL1 = "insert into Student (name, age) values (?, ?)";
         jdbcTemplateObject.update( SQL1, name, age);

         // Get the latest student id to be used in Marks table
         String SQL2 = "select max(id) from Student";
         int sid = jdbcTemplateObject.queryForInt( SQL2 );

         String SQL3 = "insert into Marks(sid, marks, year) " + "values (?, ?, ?)";
         jdbcTemplateObject.update( SQL3, sid, marks, year);
         System.out.println("Created Name = " + name + ", Age = " + age);
         
         // to simulate the exception.
         throw new RuntimeException("simulate Error condition") ;
      } 
      catch (DataAccessException e) {
         System.out.println("Error in creating record, rolling back");
         throw e;
      }
   }
   public List<StudentMarks> listStudents() {
      String SQL = "select * from Student, Marks where Student.id = Marks.sid";
      List <StudentMarks> studentMarks = jdbcTemplateObject.query(SQL, 
         new StudentMarksMapper());
      
      return studentMarks;
   }
}

Passons maintenant au fichier principal de l'application MainApp.java, qui est comme suit

package com.tutorialspoint;

import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      StudentDAO studentJDBCTemplate = 
         (StudentDAO)context.getBean("studentJDBCTemplate");
      
      System.out.println("------Records creation--------" );
      studentJDBCTemplate.create("Zara", 11, 99, 2010);
      studentJDBCTemplate.create("Nuha", 20, 97, 2010);
      studentJDBCTemplate.create("Ayan", 25, 100, 2011);

      System.out.println("------Listing all the records--------" );
      List<StudentMarks> studentMarks = studentJDBCTemplate.listStudents();
      
      for (StudentMarks record : studentMarks) {
         System.out.print("ID : " + record.getId() );
         System.out.print(", Name : " + record.getName() );
         System.out.print(", Marks : " + record.getMarks());
         System.out.print(", Year : " + record.getYear());
         System.out.println(", Age : " + record.getAge());
      }
   }
}

Voici le fichier de configuration Beans.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns:tx = "http://www.springframework.org/schema/tx"
   xmlns:aop = "http://www.springframework.org/schema/aop"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
   http://www.springframework.org/schema/tx
   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

   <!-- Initialization for data source -->
   <bean id="dataSource" 
      class = "org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name = "driverClassName" value = "com.mysql.jdbc.Driver"/>
      <property name = "url" value = "jdbc:mysql://localhost:3306/TEST"/>
      <property name = "username" value = "root"/>
      <property name = "password" value = "cohondob"/>
   </bean>
  
   <tx:advice id = "txAdvice" transaction-manager = "transactionManager">
      <tx:attributes>
      <tx:method name = "create"/>
      </tx:attributes>
   </tx:advice>
	
   <aop:config>
      <aop:pointcut id = "createOperation" 
         expression = "execution(* com.tutorialspoint.StudentJDBCTemplate.create(..))"/>
      
      <aop:advisor advice-ref = "txAdvice" pointcut-ref = "createOperation"/>
   </aop:config>
	
   <!-- Initialization for TransactionManager -->
   <bean id = "transactionManager"
      class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
      
      <property name = "dataSource" ref = "dataSource" />    
   </bean>

   <!-- Definition for studentJDBCTemplate bean -->
   <bean id = "studentJDBCTemplate"  
      class = "com.tutorialspoint.StudentJDBCTemplate">
      <property name = "dataSource" ref = "dataSource"/>  
   </bean>

</beans>

Une fois que vous avez terminé de créer les fichiers de configuration source et bean, laissez-nous exécuter l'application. Si tout va bien avec votre application, elle imprimera l'exception suivante. Dans ce cas, la transaction sera annulée et aucun enregistrement ne sera créé dans la table de base de données.

------Records creation--------
Created Name = Zara, Age = 11
Exception in thread "main" java.lang.RuntimeException: simulate Error condition

Vous pouvez essayer l'exemple ci-dessus après avoir supprimé l'exception, et dans ce cas, il devrait valider la transaction et vous devriez voir un enregistrement dans la base de données.