seata-1.2-mybatis-plus

本文介绍了如何在Seata 1.2版本中整合Mybatis-Plus,详细讲解了pom依赖、数据源配置、YML设置以及测试例子。测试例子包括通过Feign进行服务间调用,并提醒注意AOP的使用,特别是在跨服务调用时需要开启全局事务。同时指出,若入口方法未加入GlobalTransactional注解,内部方法调用不会回滚,需借助接口实现事务管理。
摘要由CSDN通过智能技术生成
  1. pom依赖
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
  1. 数据源配置
@Configuration
@Slf4j
public class DataSourceConfiguration {
    @Autowired(required = true)
    private DataSourceProperties dataSourceProperties;
   // private final static Logger logger = LoggerFactory.getLogger(SeataAutoConfig.class);
    private DataSourceProxy dataSourceProxy;

    @Bean(name = "dataSource") // 声明其为Bean实例
    @Primary // 在同样的DataSource中,首先使用被标注的DataSource
    public DataSource druidDataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        log.info("dataSourceProperties.getUrl():{}", dataSourceProperties.getUrl());
        druidDataSource.setUrl(dataSourceProperties.getUrl());
        druidDataSource.setUsername(dataSourceProperties.getUsername());
        druidDataSource.setPassword(dataSourceProperties.getPassword());
        druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
        druidDataSource.setInitialSize(0);
        druidDataSource.setMaxActive(180);
        druidDataSource.setMaxWait(60000);
        druidDataSource.setMinIdle(0);
        druidDataSource.setValidationQuery("Select 1 from DUAL");
        druidDataSource.setTestOnBorrow(false);
        druidDataSource.setTestOnReturn(false);
        druidDataSource.setTestWhileIdle(true);
        druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
        druidDataSource.setMinEvictableIdleTimeMillis(25200000);
        druidDataSource.setRemoveAbandoned(true);
        druidDataSource.setRemoveAbandonedTimeout(1800);
        druidDataSource.setLogAbandoned(true);
        log.info("装载dataSource........");
        dataSourceProxy = new DataSourceProxy(druidDataSource);
        return dataSourceProxy;
    }

    /**
     * init datasource proxy
     *
     * @Param: druidDataSource datasource bean instance
     * @Return: DataSourceProxy datasource proxy
     */
    @Bean
    public DataSourceProxy dataSourceProxy() {
        log.info("代理dataSource........");
        return dataSourceProxy;
    }

    /**
     * init global transaction scanner
     *
     * @Return: GlobalTransactionScanner
     */
    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
        log.info("配置seata........");
        return new GlobalTransactionScanner("test-service", "test-group");
    }
}
  1. yml
spring:
  application:
    name: server1
  main:
    allow-bean-definition-overriding: true
  cloud:
    alibaba:
      seata:
        tx-service-group: service-user-provider-group
  1. 测试例子
    (1) server1调用测试代码
@RestController
@RequestMapping("/seata")
public class TestRest {
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private TestFeign testFeign;

    @GetMapping("/test")
    @GlobalTransactional(rollbackFor = Exception.class)
    public RestResponse tetSeata(Integer abc) throws Exception {
        goodsService.incUv(24);
        testFeign.tetSeata2(abc);
        return ResultUtils.setOk();
    }
}

feign

@FeignClient(name = "server2", contextId = "TestFeign")
public interface TestFeign {
    @GetMapping("/seata/test2")
    Response tetSeata2(@RequestParam("abc") Integer abc);
}

(2)server2调用测试代码
同server1类似配置数据源及yml的配置项

@RestController
@RequestMapping("/seata")
public class TestRest {
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private Wo wo;

    @GetMapping("/test2")
    @GlobalTransactional(rollbackFor = Exception.class)
    public Response tetSeata2(Integer abc) {
        goodsService.incUv(24);
        if(abc != null && abc > 0){
            throw  new ServiceIllegalException("123");
        }
//        //test222();
        //wo.test222();
        return ResultUtils.setOk();
    }

    @GlobalTransactional(rollbackFor = Exception.class)
    private void test222(){
        schemeGoodsService.incUv(24);
        throw  new ServiceIllegalException("123");
    }
}

AOP

@Aspect
@Component
@Slf4j
public class TestAspect {
    @Before("execution(* com.test.test.*.*(..))")
    public void before(JoinPoint joinPoint) throws TransactionException {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
        tx.begin(300000, "test-client");
    }

    @AfterThrowing(throwing = "e", pointcut = "execution(* com.test.test.*.*(..))")
    public void doRecoveryActions(Throwable e) throws TransactionException {
        log.info("方法执行异常:{}", e.getMessage());
        if (!StringUtils.isBlank(RootContext.getXID()))
            GlobalTransactionContext.reload(RootContext.getXID()).rollback();
    }

    @AfterReturning(value = "execution(* com.test.test.*.*(..))", returning = "result")
    public void afterReturning(JoinPoint point, Object result) throws TransactionException {
        log.info("方法执行结束:{}", result);
        if (result != null) {
            if (!StringUtils.isBlank(RootContext.getXID())) {
                log.info("分布式事务Id:{}", RootContext.getXID());
                GlobalTransactionContext.reload(RootContext.getXID()).commit();
            }
        }
    }
}
public interface Wo {
    void test222();
}
@Service
public class WoImpl implements Wo {
    @Autowired
    private GoodsService goodsService;
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void test222() {
        goodsService.incUv(24);
        throw new ServiceIllegalException("123");
    }
}

注意事项:

  1. 如果通过feign调用不同服务需要开启AOP的处理(都开启了GlobalTransactional)。未开启则不会回滚多个服务调用。
  2. 入口没有加GlobalTransactional,则直接内部方法调用不会回滚,需要使用接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值