JPA+Jta-atomikos实现分布式事务

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

/**

  • @Author 一一哥Sun
  • @Date Created in 2020/4/3
  • @Description Description
    */
    @Repository
    public interface UserRepository extends JpaRepository<User, Long>,JpaSpecificationExecutor {
    }

#### **6. 配置数据源及事务管理器等**


这里的配置是最关键的,一般代码出问题都是因为这里有问题。



> 
> *这里针对两个数据库,分别设置两个数据源goodsDataSource与userDataSource。这里的DataSource必须是XADataSource类型的数据源才行,并且利用AtomikosDataSourceBean讲数据源配置进去。*
>   
> 
> *还有分别设置实体类管理工厂goodsEntityManagerFactory与userEntityManagerFactory。*
>   
> 
> *再分别设置事务管理器goodsTransactionManager与userTransactionManager。*
>   
> 
> *还要创建一个用来整合多个事务管理器的JtaTransactionManager,负责回滚到多个数据源中。*
>   
> 
> *但要注意区分是否是Primary配置。*
> 


**db1数据源配置类GoodsDataSourceConfig**



package com.yyg.boot.config;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Objects;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/18

  • @Description 商品数据源配置类
    */
    @Configuration
    @EnableJpaRepositories(basePackages = {“com.yyg.boot.dao.db01”}, entityManagerFactoryRef = “goodsEntityManagerFactory”, transactionManagerRef = “goodsTransactionManager”)
    public class GoodsDataSourceConfig {

    @Resource
    private JpaProperties jpaProperties;

    /**

    • 第一个数据源
      */
      @Primary
      @Bean(name = “goodsDataSource”)
      public DataSource goodsDataSource() {
      DruidXADataSource druidXADataSource = new DruidXADataSource();
      druidXADataSource.setUrl(“jdbc:mysql://localhost:3306/db1?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC”);
      druidXADataSource.setUsername(“root”);
      druidXADataSource.setPassword(“syc”);
      druidXADataSource.setDefaultAutoCommit(false);
      AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
      atomikosDataSourceBean.setXaDataSource(druidXADataSource);
      atomikosDataSourceBean.setUniqueResourceName(“goodsDataSource”);
      atomikosDataSourceBean.setPoolSize(5);

      return atomikosDataSourceBean;
      }

    /**

    • 商品实体类管理工厂
      */
      @Primary
      @Bean(name = “goodsEntityManagerFactory”)
      public LocalContainerEntityManagerFactoryBean goodsEntityManagerFactory(EntityManagerFactoryBuilder builder) {
      return builder.dataSource(goodsDataSource())
      .properties(jpaProperties.getProperties())
      //设置实体类所在位置:类或包
      .packages(“com.yyg.boot.entity.db1”)
      //持久化单元名称
      .persistenceUnit(“goodsPersistenceUnit”)
      .build();
      }

    /**

    • 商品事务管理器
      */
      @Primary
      @Bean(name = “goodsTransactionManager”)
      public PlatformTransactionManager goodsTransactionManager(EntityManagerFactoryBuilder builder) {
      return new JpaTransactionManager(Objects.requireNonNull(goodsEntityManagerFactory(builder).getObject()));
      }

}


**db4数据源配置类GoodsDataSourceConfig**



package com.yyg.boot.config;

import com.alibaba.druid.pool.xa.DruidXADataSource;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Objects;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/18

  • @Description 商品数据源配置类
    */
    @Configuration
    @EnableJpaRepositories(basePackages = {“com.yyg.boot.dao.db02”},entityManagerFactoryRef = “userEntityManagerFactory”,transactionManagerRef = “userTransactionManager”)
    public class UserDataSourceConfig {

    /**

    • 自动注入jpa配置
      */
      @Resource
      private JpaProperties jpaProperties;

    @Bean(name = “userDataSource”)
    public DataSource db4DataSource() {
    DruidXADataSource druidXADataSource = new DruidXADataSource();
    druidXADataSource.setUrl(“jdbc:mysql://localhost:3306/db4?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC”);
    druidXADataSource.setUsername(“root”);
    druidXADataSource.setPassword(“syc”);
    druidXADataSource.setDefaultAutoCommit(false);

     AtomikosDataSourceBean atomikosDataSourceBean = new AtomikosDataSourceBean();
     atomikosDataSourceBean.setXaDataSource(druidXADataSource);
     atomikosDataSourceBean.setUniqueResourceName("userDataSource");
     atomikosDataSourceBean.setPoolSize(5);
    
     return atomikosDataSourceBean;
    

    }

    /**

    • 将数据源、连接池、以及其他配置策略进行封装返回给事务管理器
    • 自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
      */
      @Bean(name = “userEntityManagerFactory”)
      public LocalContainerEntityManagerFactoryBean userEntityManagerFactory(EntityManagerFactoryBuilder builder){
      return builder.dataSource(db4DataSource())
      .properties(jpaProperties.getProperties())
      //设置实体类所在位置:类或包
      .packages(“com.yyg.boot.entity.db2”)
      //持久化单元名称
      .persistenceUnit(“userPersistenceUnit”)
      .build();
      }

    /**

    • 返回数据源的事务管理器
      */
      @Bean(name = “userTransactionManager”)
      public PlatformTransactionManager userTransactionManager(EntityManagerFactoryBuilder builder){
      return new JpaTransactionManager(Objects.requireNonNull(userEntityManagerFactory(builder).getObject()));
      }

}


**创建用来整合多数据源的事务管理器JtaTransactionManager**



package com.yyg.boot.config;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.jta.JtaTransactionManager;

import javax.transaction.UserTransaction;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/19

  • @Description Description
    */
    @Configuration
    public class JtaTransactionManagerConfig {

    @Primary
    @Bean(name = “jtaTransactionManager”)
    public JtaTransactionManager regTransactionManager () {
    UserTransactionManager userTransactionManager = new UserTransactionManager();
    UserTransaction userTransaction = new UserTransactionImp();
    return new JtaTransactionManager(userTransaction, userTransactionManager);
    }

}


#### **7. 创建Service及其实现类**



> 
> *注意:*
>   
> 
> *此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作,且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理。*
> 


**定义GoodsService接口**



package com.yyg.boot.service;

import com.yyg.boot.entity.db1.Goods;

import java.util.List;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/7

  • @Description Description
    */
    public interface GoodsService {

    List findAll();

    Goods addGoods(Goods goods);

}


**GoodsServiceImpl实现**



package com.yyg.boot.service.impl;

import com.yyg.boot.dao.db01.GoodsRepository;
import com.yyg.boot.entity.db1.Goods;
import com.yyg.boot.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/7

  • @Description Description

  • 注意:此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作.

  • 且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理.
    */
    @Service
    @Transactional(transactionManager = “goodsTransactionManager”,rollbackFor = Exception.class,propagation =Propagation.NEVER)
    public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsRepository goodsRepository;

    @Override
    public List findAll() {
    return goodsRepository.findAll();
    }

    @Override
    public Goods addGoods(Goods goods) {
    try {
    return goodsRepository.save(goods);
    }catch (Exception e){
    //强制手动事务回滚
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    return null;
    }

}


**定义UserService接口**



package com.yyg.boot.service;

import com.yyg.boot.entity.db2.User;

import java.util.List;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/7

  • @Description Description
    */
    public interface UserService {

    List findAll();

    User addUser(User user);

}


**UserServiceImpl实现**



package com.yyg.boot.service.impl;

import com.yyg.boot.dao.db02.UserRepository;
import com.yyg.boot.entity.db2.User;
import com.yyg.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/7

  • @Description Description

  • 注意:此处一定要通过@Transactional注解来明确指明所用的事务管理器,否则当多数据源时可能只能执行一个数据里的增删改操作.

  • 且此处应该设置Spring的事务传播属性为propagation =Propagation.NEVER,不使用单个数据源自己的事务,统一交由jtaTransactionManager的事务来管理.
    */
    @Service
    @Transactional(transactionManager = “userTransactionManager”,rollbackFor = Exception.class,propagation =Propagation.NEVER)
    public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public List findAll() {
    return userRepository.findAll();
    }

    @Override
    public User addUser(User user) {
    try {
    return userRepository.save(user);
    }catch (Exception e){
    //强制手动事务回滚
    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    }
    return null;
    }

}


#### **8. 创建Controller进行测试**



package com.yyg.boot.web;

import com.yyg.boot.entity.db1.Goods;
import com.yyg.boot.entity.db2.User;
import com.yyg.boot.service.GoodsService;
import com.yyg.boot.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**

  • @Author 一一哥Sun

  • @Date Created in 2020/4/3

  • @Description Description
    */
    @RestController
    public class TransactionController {

    @Autowired
    private UserService userService;

    @Autowired
    private GoodsService goodsService;

    @Transactional(value = “jtaTransactionManager”, rollbackFor = Exception.class)
    @GetMapping(“/add”)
    public ResponseEntity addTest() {
    Goods goods = new Goods();
    goods.setId(44L);
    goods.setName(“iPhone se”);
    goodsService.addGoods(goods);

     User user = new User();
     user.setSex("男");
     user.setUsername("一一哥");
     user.setAddress("上海");
     user.setBirthday(new Date());
     userService.addUser(user);
    
     return ResponseEntity.ok("添加成功");
    

    }

//在该接口中故意制造一个除零异常
@Transactional(value = “jtaTransactionManager”, rollbackFor = Exception.class)
@GetMapping(“/add2”)
public ResponseEntity addTest2() {
Goods goods = new Goods();
goods.setId(44L);
goods.setName(“iPhone se”);
goodsService.addGoods(goods);

给大家的福利

零基础入门

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:

在这里插入图片描述

因篇幅有限,仅展示部分资料

网络安全面试题

绿盟护网行动

还有大家最喜欢的黑客技术

网络安全源码合集+工具包

所有资料共282G,朋友们如果有需要全套《网络安全入门+黑客进阶学习资源包》,可以扫描下方二维码领取(如遇扫码问题,可以在评论区留言领取哦)~

加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0

在Hibernate和SQL Server上使用Atomikos进行事务管理的整合可以按照以下步骤进行: 1. 添加Atomikos和SQL Server的相关依赖项到你的项目中。你可以在Maven或Gradle中添加以下依赖项: ```xml <!-- Atomikos --> <dependency> <groupId>com.atomikos</groupId> <artifactId>atomikos-transactions-jta</artifactId> <version>4.0.6</version> </dependency> <dependency> <groupId>com.atomikos</groupId> <artifactId>atomikos-transactions-jdbc</artifactId> <version>4.0.6</version> </dependency> <!-- SQL Server --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>8.2.2.jre8</version> </dependency> ``` 2. 配置Atomikos的事务管理器。在Spring Boot中,可以使用`JtaTransactionManager`来配置Atomikos。 ```java @Configuration public class TransactionConfig { @Bean public UserTransactionManager userTransactionManager() throws SystemException { UserTransactionManager userTransactionManager = new UserTransactionManager(); userTransactionManager.setForceShutdown(true); return userTransactionManager; } @Bean(initMethod = "init", destroyMethod = "close") public UserTransactionImp userTransaction() throws SystemException { UserTransactionImp userTransactionImp = new UserTransactionImp(); userTransactionImp.setTransactionTimeout(300); return userTransactionImp; } @Bean public JtaTransactionManager transactionManager(UserTransactionManager userTransactionManager, UserTransactionImp userTransaction) { JtaTransactionManager transactionManager = new JtaTransactionManager(); transactionManager.setUserTransaction(userTransaction); transactionManager.setTransactionManager(userTransactionManager); return transactionManager; } } ``` 3. 配置SQL Server的数据源。可以使用Spring Boot的自动配置配置SQL Server的数据源。 ```properties spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=mydatabase spring.datasource.username=your-username spring.datasource.password=your-password spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver spring.jpa.hibernate.ddl-auto=update ``` 4. 使用Hibernate进行数据库访问。在你的实体类上使用Hibernate的注解来映射数据库表。 ```java @Entity @Table(name = "your_table") public class YourEntity { // Entity fields and annotations } ``` 5. 在需要进行事务管理的方法或类上使用`@Transactional`注解。这将确保方法内的数据库操作在Atomikos管理的事务中执行。 ```java @Service @Transactional public class YourService { // Service methods } ``` 通过按照以上步骤配置Atomikos和SQL Server的整合,你可以实现对Hibernate和SQL Server的分布式事务管理。Atomikos将协调和管理涉及多个数据库的事务,确保事务的一致性和原子性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值