原文:https://segmentfault.com/a/1190000016718525?utm_source=tag-newest

最近公司使用分布式框架搭建自己的服务(springCloud),就会遇到各位大神都会遇到的神级烦问题:分布式事务问题,近期研究了一下lcn框架的源码,觉得很不错,于是果断选用lcn控制分布式事务。选用原因如下:

1.完全开源,可以在官方的基础上做自己的各种修改
2.不仅支持springCloud,而且支持dubbo
3.数据库方面,支持mybatis,jdbc等正如lcn官网所说: LCN并不生产事务,LCN只是本地事务的协调者
官网(http://www.txlcn.org)

情景分析

假如现在你要通过携程官网买上海到大理的机票,而正好没有上海直达大理的飞机,因此你需要从昆明中转。此时伟大的携程已经给你推荐了一条最优的中转路线
(东航)上海->昆明 + (南航) 昆明->大理
你觉得满意,于是屁颠屁颠的准备一键下单了....
我们来分析一下,你点击下单以后,携程做了哪些事:

(ps 如果携程这样做:1.先看东航有没有上海到昆明的票,有,扣票,付钱,提交事务2.再看南航有没有昆明到大理的票,有,扣票,付钱,提交事务但是,刚好有那么一次,做完1后,发现2居然没票了!!你就郁闷了,你本来想到大理,但是你只买了去昆明的票,你肯定不乐意
)

首先携程向东航尝试性发送扣票请求(不提交扣票的事务),如果有票,好,继续向南航发送尝试性扣票请求(不提交扣票的事务),如果都有票,那么一次性提交两边的事务,如果没有一边没票,则回滚两个事务.

综上,我们可不可以通过一个三方,来控制我们各个模块的事务呢,答案肯定是有的,LCN就是

下面,先阐述怎么集成,怎么使用,然后下一篇文章阐述源码分析
(5.0.2版本集成:https://segmentfault.com/a/11...)

怎么集成

前提:springCloud服务是使用feign实现内部服务之间的通信

pom.xml坐标(今天是2018.10.17,最新的是4.1.0版本):
(<lcn.last.version>4.1.0</lcn.last.version>)<dependency><groupId>com.codingapi</groupId><artifactId>transaction-springcloud</artifactId><version>${lcn.last.version}</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>*</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.codingapi</groupId><artifactId>tx-plugins-db</artifactId><version>${lcn.last.version}</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>*</artifactId></exclusion></exclusions></dependency>

我们知道,feign是基于RequestTemplate模拟的http发送的请求,如果有研究feign的源码,我们可以发现在SynchronousMethodHandler 类下面,有一个targetRequest(RequestTemplate template)方法,这个方法里面会循环的调用interceptor.apply(template);
而lcn正是重写了apply方法,将自己的group-id传递到了下一方:
TransactionRestTemplateInterceptor.apply()
而如果我们项目使用了oauth2或者其他安全框架,使用feign调用的时候,
就会出现401的问题,意思是没有权限访问下一个模块,因此,我们需要将token封装在请求头里面,然后再封装。这个类的完成代码如下:

  *****一定要注意,这个类的包路径,要是这个: package com.codingapi.tx.springcloud.feign****即在自己项目新建一个这个绝对路径的类,以此来让jvm走我们自定义的类public class TransactionRestTemplateInterceptor implements RequestInterceptor {private Logger logger = LoggerFactory.getLogger(TransactionRestTemplateInterceptor.class);public TransactionRestTemplateInterceptor() {}public void apply(RequestTemplate requestTemplate) {TxTransactionLocal txTransactionLocal = TxTransactionLocal.current();String groupId = txTransactionLocal == null ? null : txTransactionLocal.getGroupId();this.logger.info("LCN-SpringCloud TxGroup info -> groupId:" + groupId);RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();HttpServletRequest request = requestAttributes == null ? null : ((ServletRequestAttributes) requestAttributes).getRequest();Object attribute = request.getAttribute("OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE");String token = attribute == null ? null : attribute.toString();requestTemplate.header("Authorization", "Bearer " + token);if (txTransactionLocal != null) {requestTemplate.header("tx-group", new String[]{groupId});}}
}

这个包路径下,还要有这两个类:

/***  Created by liuliang on 2018/10/10.*/@Service
public class TxManagerHttpRequestServiceImpl implements TxManagerHttpRequestService{@Override
public String httpGet(String url) {System.out.println("httpGet-start");String res = HttpUtils.get(url);System.out.println("httpGet-end");return res;
}@Override
public String httpPost(String url, String params) {System.out.println("httpPost-start");String res = HttpUtils.post(url,params);System.out.println("httpPost-end");return res;
}

}

//----------------------类分割线---------------------
/*** Created by liuliang on 2018/10/10.*/
@Service
public class TxManagerTxUrlServiceImpl implements TxManagerTxUrlService{
@Value("${tm.manager.url}")
private String url;@Override
public String getTxUrl() {System.out.println("load tm.manager.url ");return url;
}

}

做好这些之后,我们需要将三方控制事务的代码(tx-manager)拿过来,启动并注册到我们自己的eureka上面。这边给出官方code:https://github.com/codingapi/...

我们拉下来以后,启动tx-manager,并注意以下三个配置:

#服务端口
server.port=7000#tx-manager不得修改!!!!!!
spring.application.name=tx-manager#eureka 地址(注册到自己的eureka)
eureka.client.service-url.defaultZone=http://127.0.0.1:8880/eureka/

ok,现在我们启动了tx-manager,再回头看我们自己的项目配置,在自己项目配置(.yml)里面加上如下:

init-db: true
#txmanager地址
tm:manager:url: http://127.0.0.1:7000/tx/manager/
logging:level:com:codingapi: debug##Ribbon的负载均衡策略
ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRuleMaxAutoRetriesNextServer: 0

最后,我们还需要加上一个配置文件,加到项目的根目录下面:
tx.properties

url=http://127.0.0.1:7000/tx/manager/

怎么使用

//事务发起方:@TxTransaction(isStart = true)
/*** 测试分布式事务*/
@TxTransaction(isStart = true)
@Transactional
public void testM() {MallUser user = mallUserMapper.selectList(new EntityWrapper<MallUser>()).get(0);Random random = new Random();int i = random.nextInt(100);user.setName(i + "FF");mallUserMapper.updateById(user);log.info("i:" + i);MallItem mallItem = itemFeign.getItemById(1 + "");mallItem.setItemDetail(i + "FF");Boolean aBoolean = itemFeign.updateItemById(mallItem);log.info("item:" + aBoolean);throw new RuntimeException("333");}//事务参与方@TxTransaction@Transactional@TxTransaction
public Boolean updateItemById(MallItem mallItem){boolean b = this.updateById(mallItem);
//        throw new RuntimeException("33");return b;
}

好了,通过以上步骤,分布式事务框架就集成成功了,当然一次就成功基本上不太可能,如果大家在集成的过程中,碰到什么问题,可以上lcn分布式事务框架的官网(http://www.txlcn.org)
最后附上上面安装需要的代码,配置等:
链接:https://pan.baidu.com/s/1ulBb... 
提取码:cftf

SpringCloud集成分布式事务LCN (一)相关推荐

  1. springCloud集成分布式事务LCN 5.0.2

    TX-LCN的3种模式 LCN5.0.2有3种模式,分别是LCN模式,TCC模式,TXC模式 LCN模式: LCN模式是通过代理Connection的方式实现对本地事务的操作,然后在由TxManage ...

  2. 基于SpringCloud的分布式事务框架(LCN)

    框架特点 支持各种基于spring的db框架 兼容springcloud.dubbo 使用简单,代码完全开源 基于切面的强一致性事务框架 高可用,模块可以依赖dubbo或springcloud的集群方 ...

  3. SpringCloud入门 - 分布式事务【概念、常见框架选择 - tx-lcn】

    分布式事务简介: 事务: 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 本地事务:  SqlSessionfactory   --> 一个数据库范围类事务管理. 分 ...

  4. SpringCloud(6) 分布式事务【概念、常见框架选择 - tx-lcn】

    分布式事务简介: 事务: 指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 本地事务:  SqlSessionfactory   --> 一个数据库范围类事务管理. 分 ...

  5. SpringCloud 之分布式事务解决方案

    文章目录 分布式事务几种方案 2PC 模式 柔性事务-TCC 事务补偿型方案 柔性事务-可靠消息+最终一致性方案(异步确保型) 分布式事务几种方案 2PC 模式 是一种刚性事务,遵循ACID原则,强一 ...

  6. 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

    在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据源这里就定义为至少连接两个及以上的数据库了. 下面列举两种常用的场景: 一种是读写分离的数据源,例如一个读库和一个写库,读库负责各 ...

  7. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

      读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作.   目前有多种方式实现读写分 ...

  8. SpringCloud(7) LCN分布式事务框架入门

    官网:http://www.txlcn.org/ LCN原理:https://github.com/codingapi/tx-lcn/wiki/LCN%E5%8E%9F%E7%90%86 入门测试: ...

  9. SpringCloud - LCN分布式事务框架

    官网:http://www.txlcn.org/ LCN原理:https://github.com/codingapi/tx-lcn/wiki/LCN%E5%8E%9F%E7%90%86 入门测试: ...

  10. SpringCloud整合TX-LCN5.0.2使用LCN模式实现分布式事务

    一.TM配置 pom.xml文件中添加依赖: <dependency><groupId>com.codingapi.txlcn</groupId><artif ...

最新文章

  1. 在64位的环境中使用VS建立Web项目进行Oracle连接需要注意WebDev是32位的
  2. 敏捷转型该怎么转?来看看这本书怎么说的吧
  3. javascript核心
  4. MySQL 备份与主从复制
  5. python第9周小测验答案_智慧树_Python程序设计基础_章节测验答案
  6. Swoole入门指南:PHP7安装Swoole详细教程(一)
  7. Linux多线程开发-线程同步-读写锁pthread_rwlock_t
  8. ZooKeeper学习第一期---Zookeeper简单介绍
  9. vista下推荐大家用foobar2000播放器
  10. HDU6266 - Hakase and Nano 狄利克雷卷积
  11. 淘宝API接口:item_cat_get - 获得淘宝商品类目
  12. matlab位图矢量化,位图矢量化的处理算法研究
  13. A类业余电台操作证书考试内容提要
  14. win10开机桌面假死鼠标能动怎么办
  15. 《SolidCAM+SolidWorks 2014中文版数控加工从入门到精通》——第1章 SolidCAM基础 1.1 CAD/CAM基础...
  16. x264命令参数与代码中变量的对应关系
  17. 用excel/WPS制作酷炫数据可视化大屏(附模板)
  18. php 公众号 群发,微信公众号【服务号】群发策略调整,并开通高级群发接口
  19. Windows Server 2003服务器群集创建和配置指南
  20. 电影中牛掰的黑客技术,看这篇文章你就够了!

热门文章

  1. ssl证书链的验证的其它方式
  2. Aop 是面向切面编程,
  3. MQTT的学习研究(十)【转】mosquitto——一个开源的mqtt代理
  4. Android开发学习笔记(11):NDK与Cygwin配置手顺
  5. Midletinfo-探索手机javaME系统信息的实用工具
  6. 全班100名同学抽奖c语言,C语言综合设计实验-1-班级同学录程序设计.pptx
  7. 转发技术风雨三十年,你经历过……
  8. linux下c语言动态库生成方法
  9. F - XOR Equation CodeForces - 635C (数学)
  10. 4077. k显性字符