什么是fescar?

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

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

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

Spring Boot如何集成fescar?

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

  

  和很多2PC提交协议(如tx_lcn)的解决方案一样,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用于标识一个局部事务属于哪个全局事务,需要在调用链路的上下文中传递)传递到上层调用链路。

@Component
public 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文件,用于告诉客户端如何与分布式协调器通信,官方示例中有这个文件,就不在此贴代码啦,application.conf传送门

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

  demo地址:https://github.com/dk-lockdown/seata-demo

  集成代码:dk-foundation seata分支(https://github.com/dk-lockdown/dk-foundation/tree/dev-seata

last thing

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

Spring Boot微服务如何集成fescar解决分布式事务问题?的更多相关文章

  1. Spring Boot 微服务应用集成Prometheus + Grafana 实现监控告警

    Spring Boot 微服务应用集成Prometheus + Grafana 实现监控告警 一.添加依赖 1.1 Actuator 的 /prometheus端点 二.Prometheus 配置 部 ...

  2. 【原创】Docker容器及Spring Boot微服务应用

    Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复杂问题 传统项目实施过程中经常会出现“程序在我这跑得好好的,在你那怎么就不 ...

  3. 【spring boot】spring cloud下spring boot微服务启动没有报错,但是访问访问不到

    spring cloud下spring boot微服务启动没有报错,但是访问访问不到 解决方法: 可能是端口被占用了,但是依旧启用成功了. 更改一下项目启用的端口号,再重新启动查看是否可以正常访问.

  4. Spring Boot微服务架构入门

    概述 还记得在10年毕业实习的时候,当时后台三大框架为主流的后台开发框架成软件行业的标杆,当时对于软件的认识也就是照猫画虎,对于为什么会有这么样的写法,以及这种框架的优势或劣势,是不清楚的,Sprin ...

  5. 基于Centos7.4搭建prometheus+grafana+altertManger监控Spring Boot微服务(docker版)

    目的:给我们项目的微服务应用都加上监控告警.在这之前你需要将 Spring Boot Actuator引入 本章主要介绍 如何集成监控告警系统Prometheus 和图形化界面Grafana 如何自定 ...

  6. 使用http://start.spring.io/构建maven微服务项目的几个坑及eclipse构建spring boot微服务项目

    一,使用http://start.spring.io/构建maven微服务项目 本来嘛,直接构建的项目导入时没有任何问题的导入就可以运行,可是最近构建好项目,然后导入,种种报错 1.导入之后POM报错 ...

  7. 在spring boot微服务中使用JWS发布webService

    发布时间:2018-11-22   技术:Java+spring+maven   概述 在springboot微服务中使用JWS发布webService,在服务启动时自动发布webservice接口. ...

  8. Spring Boot微服务框架的搭建

    (1)spring boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发 ...

  9. Spring Boot微服务电商项目开发实战 --- 基础配置及搭建

    根据SpringBoot实现分布式微服务项目近两年的开发经验,今天决定开始做SpringBoot实现分布式微服务项目的系列文章,帮助其他正在使用或计划使用SringBoot开发的小伙伴们.本次系列文章 ...

随机推荐

  1. 将jar包安装到本地repository中

    mvn install:install-file -Dfile=G:/lcn_springboot2.0/tx-plugins-db-4.1.2.jar -DgroupId=com.codingapi ...

  2. for和for in区别

    for ... in 循环中的代买每执行一次,就会对数组的元素或者对象的属性进行一次循环操作. eg:应该用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”. for (变量 in 对象 ...

  3. KendoUI 自定义CheckBoxList

    不多说直接上代码 CSS完整代码: .e-selectboxs-container { display: table; } .e-selectbox { min-width: 100px; heigh ...

  4. 运用Turtle实现汉诺塔的可视化运行(递归算法)

    运用Turtle实现汉诺塔的可视化运行(递归算法) 汉诺塔问题又名河内塔问题,是源于印度一个古老传说的益智玩具.大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆 ...

  5. Linux之prink原理

    我的分析是基于Linux4.15.1 1.看看kernel是如何调用到console初始化函数的: 分两条线: a.start_kernel  -->  console_init   --> ...

  6. Python 找零问题

    #coding = utf-8 def Change_Money(money): print('总金额:'+str(money)+'元') loop=True tmp=[] # 面值列表 单位:元 t ...

  7. tensorflow 代码阅读

    具体实现: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/framework 『深度长文』Tensorflo ...

  8. javascript dom页面中的location属性

    属性名称 host:设置或返回主机名和当前URL的端口号 hostname:设置或 返回当前的URL的主机名 href:设置或返回完整的url,可用于设置跳转 hash:设置或返回从#号开始的URL锚 ...

  9. click python cli 开发包

    python click 包是一个方便的cli 开发包,我们可以用来开发强大的cli 应用 使用venv 进行环境准备,示例代码来自官方 venv 环境准备 python3 -m venv demoa ...

  10. Computer Graphics Principles And Practice (James Foley / Andries Van Dam / Morgan McGuire / David Sklar / James D. Foley 著)

    1 Introduction 2 Introduction to 2D Graphics Using WPF 3 An Ancient Renderer Made Modern 4 A 2D Grap ...