Maison  >  Article  >  Java  >  Comment utiliser les composants JTA pour implémenter la gestion des transactions multi-sources de données dans SpringBoot2

Comment utiliser les composants JTA pour implémenter la gestion des transactions multi-sources de données dans SpringBoot2

王林
王林avant
2023-05-10 22:07:041914parcourir

1. Introduction aux composants JTA

1. Concepts de base de JTA

JTA est Java-Transaction-API qui permet aux applications d'effectuer un traitement de transactions distribué, c'est-à-dire d'accéder et de mettre à jour des données sur deux ou plusieurs ressources informatiques du réseau. La prise en charge de JTA par le pilote JDBC améliore considérablement les capacités d'accès aux données.

Le protocole XA est un ensemble de spécifications de gestion de transactions distribuées au niveau de la base de données. JTA est l'implémentation du protocole XA en Java. Plusieurs bases de données ou fournisseurs de messages implémentent l'interface JTA. Les développeurs n'ont besoin que d'appeler l'interface SpringJTA pour implémenter JTA. fonctions de gestion des transactions.

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 à une base de données. N'importe lequel des composants de plate-forme Java suivants peut participer à une transaction JTA

2. Transaction distribuée

La transaction distribuée comprend un gestionnaire de transactions (TransactionManager) et un ou plusieurs gestionnaires de ressources prenant en charge le protocole XA (Resource Manager).

Un gestionnaire de ressources est tout type de conteneur de stockage de données persistant, tel que les bases de données relationnelles couramment utilisées en développement : MySQL, Oracle, etc., et les middlewares de messages RocketMQ, RabbitMQ, etc.

Le gestionnaire de transactions fournit des fonctions telles que la déclaration de transaction, la gestion des ressources de transaction, la synchronisation et la propagation du contexte de transaction, et est responsable de la communication mutuelle de tous les participants à la transaction dans l'unité. La spécification JTA définit l'interface permettant au gestionnaire de transactions d'interagir avec d'autres participants à la transaction, et aux autres participants à la transaction d'interagir avec le gestionnaire de transactions.

2. SpringBoot intègre JTA

Schéma de structure global du projet

Comment utiliser les composants JTA pour implémenter la gestion des transactions multi-sources de données dans SpringBoot2

1 Dépendances principales

<!--SpringBoot核心依赖-->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!--JTA组件核心依赖-->
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-jta-atomikos</artifactid>
</dependency>

2. Configuration de l'environnement

La configuration de jtaManager ici est très critique dans la sortie du journal.

spring:
  jta:
    transaction-manager-id: jtaManager
  # 数据源配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    data01:
      driverClassName: com.mysql.jdbc.Driver
      dbUrl: jdbc:mysql://localhost:3306/data-one
      username: root
      password: 000000
    data02:
      driverClassName: com.mysql.jdbc.Driver
      dbUrl: jdbc:mysql://localhost:3306/data-two
      username: root
      password: 000000

3. Conteneur principal

Les méthodes de configuration des deux connexions à la base de données ici sont les mêmes, et vous pouvez les télécharger et les lire dans le code source. L'idée de base est de confier la source de données au composant JTA pour une gestion unifiée afin de faciliter la communication des transactions.

Paramètres de la source de données

@Component
@ConfigurationProperties(prefix = "spring.datasource.data01")
public class DruidOneParam {
    private String dbUrl;
    private String username;
    private String password;
    private String driverClassName;
}

Configuration des composants JTA

package com.jta.source.conifg;
@Configuration
@MapperScan(basePackages = {"com.jta.source.mapper.one"},sqlSessionTemplateRef = "data01SqlSessionTemplate")
public class DruidOneConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(DruidOneConfig.class) ;
    @Resource
    private DruidOneParam druidOneParam ;
    @Primary
    @Bean("dataSourceOne")
    public DataSource dataSourceOne () {
        // 设置数据库连接
        MysqlXADataSource mysqlXADataSource = new MysqlXADataSource();
        mysqlXADataSource.setUrl(druidOneParam.getDbUrl());
        mysqlXADataSource.setUser(druidOneParam.getUsername());
        mysqlXADataSource.setPassword(druidOneParam.getPassword());
        mysqlXADataSource.setPinGlobalTxToPhysicalConnection(true);
        // 事务管理器
        AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
        atomikosDataSourceBean.setXaDataSource(mysqlXADataSource);
        atomikosDataSourceBean.setUniqueResourceName("dataSourceOne");
        return atomikosDataSourceBean;
    }
    @Primary
    @Bean(name = "sqlSessionFactoryOne")
    public SqlSessionFactory sqlSessionFactoryOne(
            @Qualifier("dataSourceOne") DataSource dataSourceOne) throws Exception{
        // 配置Session工厂
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSourceOne);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactory.setMapperLocations(resolver.getResources("classpath*:/dataOneMapper/*.xml"));
        return sessionFactory.getObject();
    }
    @Primary
    @Bean(name = "data01SqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(
            @Qualifier("sqlSessionFactoryOne") SqlSessionFactory sqlSessionFactory) {
        // 配置Session模板
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

4. Comparaison des tests

Ici, nous comparons les résultats des tests de deux méthodes Lorsque vous effectuez des opérations de données entre deux sources de données, il vous suffit d'utiliser l'interface. Ajoutez simplement l'annotation @Transactional à la méthode pour garantir la cohérence des données entre les deux sources de données.

@Service
public class TransferServiceImpl implements TransferService {
    @Resource
    private UserAccount01Mapper userAccount01Mapper ;
    @Resource
    private UserAccount02Mapper userAccount02Mapper ;
    @Override
    public void transfer01() {
        userAccount01Mapper.transfer("jack",100);
        System.out.println("i="+1/0);
        userAccount02Mapper.transfer("tom",100);
    }
    @Transactional
    @Override
    public void transfer02() {
        userAccount01Mapper.transfer("jack",200);
        System.out.println("i="+1/0);
        userAccount02Mapper.transfer("tom",200);
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer