本地事务,分布式事务

本地事务在分布下的问题

@Transactional 本地事务,此方法虽然已经添加该注解,但仍会产生一些问题:

1.第四步,远程服务其实成功了。但由于网络问题故障等问题没有返回,此方法回滚了,但是远程服务中的方法不能回滚,也就是说订单回滚,库存却扣减!

2.第五步异常,使方法回滚,但是此时第四步已经执行完成

分布式CAP

 

RAFT算法动画演示

http://thesecretlivesofdata.com/raft/

 

 

download
来源:默认下载

 

Seata控制分布式步骤

1.每一个微服务先必须创建undo_log表

-- 注意此处0.3.0+ 增加唯一索引 ux_undo_log
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2.安装事务协调器:https://github.com/seata/seata/releases

3.整合:

  • (1)导入依赖 spring-cloud-starter-alibaba-seata    大事务 方法上面标注 @GlobalTransactional
  • (2)修改下载好的seata的配置文件 registry.conf  type=nacos
  • (3)所有想要用到分布式事务的微服务使用seata DataSourceProxy代理自己的数据源,加下面的配置
  •     @Autowired
        DataSourceProperties dataSourceProperties;
        @Bean
        public DataSource dataSource(DataSourceProperties dataSourceProperties){
            HikariDataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
            if(StringUtils.hasText(dataSourceProperties.getName())){
                dataSource.setPoolName(dataSourceProperties.getName());
            }
            return new DataSourceProxy(dataSource);
        }
  • (4)每个微服务,都需要导入 registry.conf  file.conf(31行 修改   vgroup_mapping.gulimall-product-fescar-service-group = "default")

但是在订单服务这里 分布式事务 不使用seata,效率低下

最终解决方案:柔性事务-可靠消息+最终一致性方案(异步确保型)

 

 

 

阅读剩余
THE END