博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring Boot微服务如何集成fescar解决分布式事务问题?
阅读量:5089 次
发布时间:2019-06-13

本文共 4196 字,大约阅读时间需要 13 分钟。

什么是fescar?

  关于fescar的详细介绍,请参阅。

  传统的2PC提交协议,会持有一个全局性的锁,所有局部事务预提交成功后一起提交,或有一个局部事务预提交失败后一起回滚,最后释放全局锁。锁持有的时间较长,会对并发造成较大的影响,死锁的风险也较高。

  fescar的创新之处在于,每个局部事务执行完立即提交,释放本地锁;它会去解析你代码中的sql,从数据库中获得事务提交前的事务资源即数据,存放到undo_log中,全局事务协调器在回滚的时候直接使用undo_log中的数据覆盖你提交的数据。

Spring Boot如何集成fescar?

  我们可以从中看到,fescar目前提供的示例是针对使用dubbo的服务,那Spring Boot的项目如何集成fescar呢?

  

  和很多2PC提交协议(如)的解决方案一样,fescar也是在数据源处做了代理,和事务协调器进行通信,来决定本地事务是否回滚。所以,第一步,在你的spring boot项目中,首先应使用fescar提供的代理数据源作为你的数据源,例如:

DruidDataSource dataSource = initDataSource(dataSourceProps.get("url").toString(), dataSourceProps.get("username").toString(), dataSourceProps.get("password").toString());            DataSourceProxy proxy = new DataSourceProxy(dataSource);

  然后,你需要创建一个Feign拦截器,把RootContext中的XID(XID用于标识一个局部事务属于哪个全局事务,需要在调用链路的上下文中传递)传递到上层调用链路。

@Componentpublic class RequestHeaderInterceptor implements RequestInterceptor {    @Override    public void apply(RequestTemplate template) {        String xid = RootContext.getXID();        if(StringUtils.isNotBlank(xid)){            template.header("Fescar-Xid",xid);        }    }}

  最后,你需要创建一个Http Rest请求拦截器,用于把当前上下文中获取到的XID放到RootContext。

import com.alibaba.fescar.core.context.RootContext;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class FescarXidFilter extends OncePerRequestFilter {    protected Logger logger = LoggerFactory.getLogger(FescarXidFilter.class);    @Override    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {        String xid = RootContext.getXID();        String restXid = request.getHeader("Fescar-Xid");        boolean bind = false;        if(StringUtils.isBlank(xid)&&StringUtils.isNotBlank(restXid)){            RootContext.bind(restXid);            bind = true;            if (logger.isDebugEnabled()) {                logger.debug("bind[" + restXid + "] to RootContext");            }        }        try{            filterChain.doFilter(request, response);        } finally {            if (bind) {                String unbindXid = RootContext.unbind();                if (logger.isDebugEnabled()) {                    logger.debug("unbind[" + unbindXid + "] from RootContext");                }                if (!restXid.equalsIgnoreCase(unbindXid)) {                    logger.warn("xid in change during http rest from " + restXid + " to " + unbindXid);                    if (unbindXid != null) {                        RootContext.bind(unbindXid);                        logger.warn("bind [" + unbindXid + "] back to RootContext");                    }                }            }        }    }}

  这样就完成了fescar的集成。

开始使用吧!

  首先在项目中初始化两个Bean:

@Bean    public FescarXidFilter fescarXidFilter(){        return new FescarXidFilter();    }    @Bean    public GlobalTransactionScanner scanner(){        GlobalTransactionScanner scanner = new GlobalTransactionScanner("fescar-test","my_test_tx_group");        return scanner;    }

  然后写两个服务,服务A调用服务B,并在A服务的调用方法上打上@GlobalTransactional标签:

@GlobalTransactional(timeoutMills = 300000, name = "fescar-test-tx")    public void testFescar() throws BusinessException {        DictionVO dictionVO = new DictionVO();        dictionVO.setCode("simidatest");        dictionVO.setValue("1");        dictionVO.setDesc("simidatest");        dictionVO.setAppId("sso");        commonService.createDiction(dictionVO);//远程调用服务B        areaMapper.deleteAreaBySysNo(2);//本地事务        throw new BusinessException("主动报错");    }

  最后,两个项目中添加application.conf文件,用于告诉客户端如何与分布式协调器通信,官方示例中有这个文件,就不在此贴代码啦,

启动事务协调器,sh fescar-server.sh 8091 ~/dksl/git/fescar/data,启动你的项目,开始测试吧!

  demo地址:

  集成代码:dk-foundation seata分支()

last thing

  分布式事务作为微服务应用中的老大难问题,在现有的解决方案中,个人认为fescar是目前最轻量并且代价最小的一种解决方案。目前的版本,事务协调器还不能分布式部署,官方给出的路线图是在三月底会有第一个生产可用版本。让我们一起参与到fescar的社区中,共同推动fescar生态建设,让落地微服务不必再担心分布式事务的问题。

转载于:https://www.cnblogs.com/DKSL/p/fescar.html

你可能感兴趣的文章
C#中集合ArrayList与Hashtable的使用
查看>>
从一个标准 url 里取出文件的扩展名
查看>>
map基本用法
查看>>
poj-1163 动态规划
查看>>
Golang之interface(多态,类型断言)
查看>>
Redis快速入门
查看>>
BootStrap---2.表格和按钮
查看>>
Linear Algebra lecture 2 note
查看>>
CRC计算模型
查看>>
Ajax之404,200等查询
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>
csv HTTP简单表服务器
查看>>
OO设计的接口分隔原则
查看>>
数据库连接字符串大全 (转载)
查看>>
java类加载和对象初始化
查看>>
对于负载均衡的理解
查看>>
django简介
查看>>
window.event在IE和Firefox的异同
查看>>
常见的js算法面试题收集,es6实现
查看>>
IO流写出到本地 D盘demoIO.txt 文本中
查看>>