English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Gestion des transactions Springboot détaillée

Dans la gestion des transactions de Spring Boot, implémenter l'interface PlatformTransactionManager.

public interface PlatformTransactionManager {
  org.springframework.transaction.TransactionStatus getTransaction(org.springframework.transaction.TransactionDefinition transactionDefinition) throws org.springframework.transaction.TransactionException;
  void commit(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;
  void rollback(org.springframework.transaction.TransactionStatus transactionStatus) throws org.springframework.transaction.TransactionException;
}

Lorsque nous utilisons spring-boot-starter-Lorsque dépendance jdbc, le cadre injecte automatiquement DataSourceTransactionManager par défaut. Nous n'avons donc pas besoin de configuration supplémentaire pour utiliser l'annotation @Transactional.

Gestionnaire de transactions jdbc

Dans le Service, les méthodes annotées @Transactional supportent les transactions. Si l'annotation est sur la classe, toutes les méthodes de la classe supportent par défaut les transactions.

Situation de gestion de plusieurs transactions

Première : vous pouvez implémenter l'interface TransactionManagementConfigurer, où la valeur de retour de la méthode est le gestionnaire de transactions par défaut.

Deuxième : vous pouvez définir value sur la méthode d'exécution spécifique

Si le conteneur Spring contient plusieurs instances de PlatformTransactionManager et qu'aucune implémentation de l'interface TransactionManagementConfigurer ne spécifie la valeur par défaut, lorsque nous utilisons l'annotation @Transactional dans une méthode, il est nécessaire de spécifier value. Si none n'est pas spécifié, une exception sera lancée.

//@EnableTransactionManagement // Activer la gestion des transactions par annotation, équivalent à la configuration XML <tx:annotation-driven />
@SpringBootApplication
public class ProfiledemoApplication implements TransactionManagementConfigurer {
  @Resource(name="txManager2}
  private PlatformTransactionManager txManager2;
  // créer manuellement un gestionnaire de transactions1 le cadre datasource sera injecté automatiquement
  //Dans le conteneur Spring, l'annotation @Bean ajoutée manuellement sera chargée en priorité, le cadre ne réinstanciera pas d'autres classes d'implémentation PlatformTransactionManager.
  @Bean(name = "txManager1}
  public PlatformTransactionManager txManager(DataSource dataSource) {
    retourner new DataSourceTransactionManager(dataSource);
  }
  // créer un gestionnaire de transactions2
  @Bean(name = "txManager2}
  public PlatformTransactionManager txManager2(EntityManagerFactory factory) {
    retourner new JpaTransactionManager(factory);
  }
  // implémenter l'interface TransactionManagementConfigurer, son retour représentant le gestionnaire de transactions par défaut dans le cas où plusieurs gestionnaires de transactions sont disponibles
  @Override
  public PlatformTransactionManager annotationDrivenTransactionManager() {
    retourner txManager2;
  }
  public static void main(String[] args) {
    SpringApplication.run(ProfiledemoApplication.class, args);
  }
}

implémentation spécifique

@Component
public class DevSendMessage implements SendMessage {
  // spécifiquement pour indiquer quel gestionnaire de transactions utiliser
  @Transactional(value="txManager1}
  @Override
  public void send() {
    System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
    send2();
  }
  @Transactional
  public void send2()) {
    System.out.println(">>>>>>>>Dev Send2() <<<<<<<<<<);
  }
}

Niveau d'isolement

public enum Isolation {
  DEFAULT(TransactionDefinition.ISOLATION_DEFAULT),
  READ_UNCOMMITTED(TransactionDefinition.ISOLATION_READ_UNCOMMITTED),
  READ_COMMITTED(TransactionDefinition.ISOLATION_READ_COMMITTED),
  REPEATABLE_READ(TransactionDefinition.ISOLATION_REPEATABLE_READ),
  SERIALIZABLE(TransactionDefinition.ISOLATION_SERIALIZABLE);
  private final int value;
  Isolation(int value) { this.value = value; }
  public int value() { return this.value; }
}
  1. DEFAULT : c'est la valeur par défaut, ce qui signifie utiliser le niveau d'isolement par défaut du niveau inférieur de la base de données. Pour la plupart des bases de données, cette valeur est généralement : READ_COMMITTED.
  2. READ_UNCOMMITTED : ce niveau d'isolement indique qu'une transaction peut lire les données modifiées par une autre transaction mais pas encore soumises. Ce niveau ne peut pas prévenir la lecture de données corrompues et la lecture non répétitive, par conséquent, ce niveau n'est rarement utilisé.
  3. READ_COMMITTED : ce niveau d'isolement indique qu'une transaction ne peut lire que les données déjà soumises par une autre transaction. Ce niveau peut prévenir la lecture de données corrompues, ce qui est également la valeur recommandée dans la plupart des cas.
  4. REPEATABLE_READ : ce niveau d'isolement indique qu'une transaction peut répéter plusieurs fois une certaine requête au cours de tout le processus, et que les enregistrements retournés sont les mêmes chaque fois. Même si de nouvelles données satisfaisant cette requête sont ajoutées entre plusieurs requêtes, ces nouveaux enregistrements seront néanmoins ignorés. Ce niveau peut prévenir la lecture de données corrompues et la lecture non répétitive.
  5. SERIALIZABLE : toutes les transactions s'exécutent en série, une après l'autre, de sorte que les transactions ne peuvent pas interférer l'une avec l'autre, c'est-à-dire, ce niveau peut prévenir la lecture de données corrompues, la lecture non répétitive et la lecture fantôme. Mais cela aura un impact important sur les performances du programme. Souvent, ce niveau n'est pas utilisé.

Spécification de la méthode : en utilisant l'attribut isolation, par exemple :

@Transactional(isolation = Isolation.DEFAULT)

Comportement de propagation

Le comportement de propagation des transactions se réfère à ce qui suit : si, avant le début de la transaction actuelle, un contexte de transaction existe déjà, plusieurs options peuvent être spécifiées pour déterminer le comportement d'exécution d'une méthode transactionnelle.

Nous pouvons voir que l'enumérateur Propagation de la classe org.springframework.transaction.annotation.Propagation définie dans}}6des valeurs d'ensemble représentant les comportements de propagation :

public enum Propagation {
  REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
  SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
  MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
  REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
  NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
  NEVER(TransactionDefinition.PROPAGATION_NEVER),
  NESTED(TransactionDefinition.PROPAGATION_NESTED);
  private final int value;
  Propagation(int value) { this.value = value; }
  public int value() { return this.value; }
}

REQUIRED : Si une transaction est en cours, la jointe à cette transaction ; si aucune transaction n'est en cours, crée une nouvelle transaction. Valeur par défaut.

SUPPORTS : Si une transaction est en cours, la jointe à cette transaction ; si aucune transaction n'est en cours, continue d'exécuter en mode non transactionnel.

MANDATORY : Si une transaction est en cours, la jointe à cette transaction ; si aucune transaction n'est en cours, lève une exception. (Forcé à être mis dans la transaction)

REQUIRES_NEW : Crée une nouvelle transaction, suspend la transaction en cours si une transaction est en cours. (Utilisé couramment pour l'écriture de journaux, même si la transaction précédente est annulée, cette transaction sera exécutée et enregistrera les informations d'erreur)

NOT_SUPPORTED : Exécute en mode non transactionnel, suspend la transaction en cours si une transaction est en cours.

NEVER : Exécute en mode non transactionnel, lève une exception si une transaction est en cours.

NESTED : Si une transaction est en cours, crée une transaction en tant que transaction imbriquée pour l'exécuter ; si aucune transaction n'est en cours, cette valeur est équivalente à REQUIRED .

Méthode spécifiée : en utilisant l'attribut propagation, par exemple :

@Transactional(propagation = Propagation.REQUIRED)

Cas où le rollback ne se produit pas

Le rollback n'a lieu que lorsque RuntimeException n'est pas capturé

Catch les exceptions lancées, les deux insertions réussiront

@Override
  @Transactional
  public void insertandinsert(Staff staff) {
    staffDao.insert(staff);
    try {
      int i = 1 / 0;
    }
      e.printStackTrace();
    }
    staffDao.insert(staff);
  }

Ajoutez la phrase : TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); dans l'instruction catch de la méthode de couche de service pour rollback manuel, la non-insertion ne se produira pas.

@Override
  @Transactional
  public void insertandinsert(Staff staff) throws Exception {
    try {
      staffDao.insert(staff);
      int i=1/0;
      staffDao.insert(staff);
    }
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
  }

Voici la totalité du contenu de cet article, j'espère qu'il vous sera utile dans vos études, et que vous soutiendrez également le tutoriel de cri.

Déclaration : le contenu de cet article est issu du réseau, propriété des auteurs originaux, contribué et téléversé par les utilisateurs d'Internet de manière spontanée. Ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme et n'assume aucune responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un email à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un email pour signaler des violations, et fournissez des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)

Vous pourriez aussi aimer