记录:微服务项目集成seata分布式事务框架坑点测试

1,496 阅读2分钟

记录:微服务项目集成seata分布式事务框架坑点测试

1.背景

项目需要进行重构,从单体架构改为微服务项目,RPC框架为spring cloud alibaba,分布式事务框架为seata。由于本人没有用过seata,所以在项目框架搭建之处,未有考虑过一些坑点。本文就其中一个内层服务重试方面的坑做了简单的测试。

2.坑点猜测

ribbon 和 feign 都是有重试的(本项目并没有采用ribbon重试,而是采用的feign重试),而当前项目并没有特殊的去做幂等,只是考虑通过数据版本来控制并发。所以猜想:某些场景(无唯一性校验或者业务数据验证)会因为重试造成逻辑重复执行,造成数据重写。

3.坑点验证

3.1.服务调用关系

外层服务:TestSeataService;依次调用内层事务:iTestBasicService,iTestInboundService

重试的内层服务是:iTestBasicService

3.2.外层事务

  • 代码
@Service
@AllArgsConstructor
public class TestSeataService {
    private ITestBasicService iTestBasicService;
    private ITestInboundService iTestInboundService;

    @GlobalTransactional
    public void test(Long id, String code) {
   		//依次调用两个内层服务
        iTestBasicService.insert(id, code);
        iTestInboundService.insert(id, code);
    }
}
  • 超时配置
feign:
  hystrix:
    enabled: true
  httpclient:
    enabled: true
  client:
    config:
      default: 
        connectTimeout: 1000
        readTimeout: 5000  #超时时间:5S

3.3.内层事务

  • TestBasicService
@Service
@AllArgsConstructor
@Transactional
public class TestBasicService {
    private static Long time = 23000L;
    private TestBasicMapper testBasicMapper;

    public Integer insert(Long id, String code) throws InterruptedException {
    	//通过全局变量递减来模拟请求从超时到不超时的场景
        Thread.sleep( time -= 5000);
        TestBasic basic = new TestBasic(id, code);
        testBasicMapper.insert(basic));
        return 1;
    }
}
  • TestInboundService
@Service
@AllArgsConstructor
@Transactional
public class TestInboundService {
    private TestInboundMapper testInboundMapper;

    public Integer insert(Long id, String code) {
        TestInbound basic = new TestInbound(id, code);
        testInboundMapper.insert(basic);
        return 1;
    }
}

3.4.结果输出

调用接口,参数如下:id=内部生成;code=15

  • 日志

    //待补充

  • 数据

    表 test_basic

    id code
    10000000971 15
    10000000972 15

    表 test_inbound:

    id code
    10000001062 15

4.结论

没有进行幂等支持的话,重试确实会产生数据问题。

5.未测试点

  • ribbon 和 feign重试均没有配置时,为什么没用5S 超时回滚,而是等待了23S执行成功了
  • TestBasicService 调用结束,服务挂掉的场景