对比LCN和saga(华为apache孵化器项目) ,LCN使用代理连接池封装补偿方法,saga需要手工写补偿方法,相对来说LCN使用更加方便。

参考官方地址:
https://github.com/codingapi/tx-lcn/wiki/TxManager%E5%90%AF%E5%8A%A8%E8%AF%B4%E6%98%8E
一. 原理

  1. 事务控制原理![在这里插入图片描述](https://img-blog.csdnimg.cn/20201127180818914.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80ODMyMTk5Mw==,size_16,color_FFFFFF,t_70#pic_center)
    

LCN事务控制原理是由事务模块TxClient下的代理连接池与TxManager的协调配合完成的事务协调控制。

TxClient的代理连接池实现了javax.sql.DataSource接口,并重写了close方法,事务模块在提交关闭以后TxClient连接池将执行"假关闭"操作,等待TxManager协调完成事务以后在关闭连接。
二. 调用时序图

  1. 正常
    

2. 异常
二. 服务端

tx-manager 4.1.0
三. 客户端

  1. pom添加依赖
    
  2. `

     <lcn.last.version>4.1.0</lcn.last.version>
    
     <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.1.1</version></dependency><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>`
    
  3. 配置文件

  4. `#Ribbon的负载均衡策略:随机

#ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule

#由于springcloud默认是开启的重试机制,开启次机制以后会导致当springcloud请求超时时会重复调用业务模块,从而会引发数据混乱,因此建议将其禁用。对于网络模块超时等故障问题建议使用hytrix方式。

#ribbon.MaxAutoRetriesNextServer=0

tm:

manager:

url: http://localhost:8899/tx/manager/

ribbon:

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

MaxAutoRetriesNextServer: 0

init-db:true

hystrix:

command:

default:execution:isolation:thread:timeoutInMilliseconds: 6000`
  1. Service包下处理http请求和对服务器的连接
    
package com.svw.tbox.tcloud.commons.ms.service;import com.codingapi.tx.netty.service.TxManagerHttpRequestService;import com.lorne.core.framework.utils.http.HttpUtils;import org.springframework.stereotype.Service;@Servicepublicclass TxManagerHttpRequestServiceImpl implements TxManagerHttpRequestService{@Overridepublic String httpGet(String url) {//GET请求前String res = HttpUtils.get(url);//GET请求后returnres;}@Overridepublic String httpPost(String url, String params) {//POST请求前String res = HttpUtils.post(url,params);//POST请求后returnres;}}package com.svw.tbox.tcloud.commons.ms.service;import com.codingapi.tx.config.service.TxManagerTxUrlService;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;@Servicepublic class TxManagerTxUrlServiceImpl implements TxManagerTxUrlService{@Value("${tm.manager.url}")private String url;@Overridepublic String getTxUrl() {//load tm.manager.urlreturn url;}}
  1. 启动类配置代理连接池
import javax.sql.DataSource;import org.mybatis.spring.annotation.MapperScan;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.cloud.netflix.hystrix.EnableHystrix;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.core.env.Environment;import com.alibaba.druid.pool.DruidDataSource;@SpringBootApplication@EnableDiscoveryClient@EnableHystrix@MapperScan(basePackages = "com.svw.tbox.tcloud.commons.ms.dao")@ComponentScan(basePackages = { "com.svw.tbox.tcloud" })publicclass MsApplication {……@Autowiredprivate Environment env;@Beanpublic DataSource dataSource() {DruidDataSource dataSource = new DruidDataSource();dataSource.setUrl(env.getProperty("spring.datasource.url"));dataSource.setUsername(env.getProperty("spring.datasource.username"));//用户名dataSource.setPassword(env.getProperty("spring.datasource.password"));//密码dataSource.setInitialSize(2);dataSource.setMaxActive(20);dataSource.setMinIdle(0);dataSource.setMaxWait(60000);dataSource.setValidationQuery("SELECT 1");dataSource.setTestOnBorrow(false);dataSource.setTestWhileIdle(true);dataSource.setPoolPreparedStatements(false);returndataSource;}

5. 测试代码

调用方tcloud-mds => 参与方tcloud-commons
1. 调用方:tcloud-mds

package com.svw.tbox.tcloud.commons.api.feign;import org.springframework.cloud.netflix.feign.FeignClient;import com.svw.tbox.tcloud.commons.api.config.TxFeignConfiguration;import com.svw.tbox.tcloud.commons.api.service.SysErrorCodeMappingService;/*** <p>ClassName: SysErrorCodeMappingFeign</p>* <p>Description: 远程调用错误码服务</p>* <p>Author: hurf</p>* <p>Date: 2017年12月11日</p>*/@FeignClient(value = "tcloud-commons-ms")publicinterface SysErrorCodeMappingFeign extends SysErrorCodeMappingService {}

2. 事务发起@TxTransaction(isStart=true)

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.codingapi.tx.annotation.TxTransaction;import com.svw.tbox.tcloud.commons.api.entity.SysErrorCodeMapping;import com.svw.tbox.tcloud.commons.api.feign.SysErrorCodeMappingFeign;import com.svw.tbox.tcloud.commons.api.service.CmnService;import com.svw.tbox.tcloud.commons.api.service.JedisTemplate;import com.svw.tbox.tcloud.commons.util.DateUtil;import com.svw.tbox.tcloud.mds.entity.ThUserLogin;/*** @Title<p>ClassName: UserTokenService</p>* @Description<p>Description: 登录服务</p>* @Author<p>Author: hurf</p>* @Date<p>Date: 2018年2月6日</p>*/@Servicepublicclass UserTokenService extends CmnService<ThUserLogin>{@Autowiredprivate JedisTemplate jedisTemplate;@Autowiredprivate SysErrorCodeMappingFeign sysErrorCodeMappingFeign;@Transactional@TxTransaction(isStart=true)public String add(SysErrorCodeMapping sysErrorCodeMapping) {// 远程调用新增sysErrorCodeMappingFeign.add(sysErrorCodeMapping);// 本地新增dbinsertSelective(ThUserLogin.builder().accessToken(sysErrorCodeMapping.getApiCode()).refreshToken(sysErrorCodeMapping.getInnerErrorCode()).createBy("测试事务").build());//本地缓存事务jedisTemplate.set("isStart", DateUtil.getNow());//      int ii = 1/0;//异常return"测试分布式事务成功";}}

3. 事务参与方tcloud-commons-ms: @Transactional

@RestControllerpublicclass SysErrorCodeMappingController implements SysErrorCodeMappingService {@Autowiredprivate MsService msService;@ApiOperation("添加错误码信息")@Overridepublic SystemResponse add(@RequestBody SysErrorCodeMapping sysErrorCodeMapping) {returnmsService.add(sysErrorCodeMapping);}。。。。。。importcom.codingapi.tx.annotation.ITxTransaction;@Service@CacheConfig(cacheNames = "sys-code-resource")publicclass MsService implements ITxTransaction{@Autowiredprivate JedisTemplate jedisTemplate;@Autowiredprivate SysErrorCodeMappingMapper sysErrorCodeMappingMapper;/*** <p>Title: 事务参与方</p>* <p>Description: </p>* @param sysErrorCodeMapping* @return*/@Transactionalpublic SystemResponse add(SysErrorCodeMapping sysErrorCodeMapping) {//db操作sysErrorCodeMapping.setVersion(1);sysErrorCodeMapping.setDelFlag(Short.valueOf("0"));sysErrorCodeMapping.setCreatedBy("admin");sysErrorCodeMapping.setCreateDate(new Date());sysErrorCodeMappingMapper.insertSelective(sysErrorCodeMapping);//redis操作jedisTemplate.set("addTest"+DateUtil.getNow(),"tttttttttttttttttttttt");return ResultUtil.success(refreshAll());}
  1. 效果
    

启动两个微服务,访问调用方接口
1. 正常情况


2. 异常回滚情况
删除刚刚的测试数据,开启异常情况:

@Transactional@TxTransaction(isStart=true)public String add(SysErrorCodeMapping sysErrorCodeMapping) {// 远程调用新增sysErrorCodeMappingFeign.add(sysErrorCodeMapping);// 本地新增dbinsertSelective(ThUserLogin.builder().accessToken(sysErrorCodeMapping.getApiCode()).refreshToken(sysErrorCodeMapping.getInnerErrorCode()).createBy("测试事务").build());//本地缓存事务jedisTemplate.set("isStart", DateUtil.getNow());intii = 1/0;//异常return"测试分布式事务成功";}



发现mysql已经回滚了,但是redis没有回滚, 目前只支持db分布式事务。

spring boot 分布式事务解决方案相关推荐

  1. dubbo分布式事务解决方案_spring boot 分布式事务解决方案

    点击上方蓝色字体,选择"标星公众号" 优质文章,第一时间送达 上一篇:这300G的Java资料是我师傅当年给我的,免费分享给大家 下一篇:这200G的Java实战资料是我师傅当年教 ...

  2. Spring Boot之基于Dubbo和Seata的分布式事务解决方案

    转载自 Spring Boot之基于Dubbo和Seata的分布式事务解决方案 1. 分布式事务初探 一般来说,目前市面上的数据库都支持本地事务,也就是在你的应用程序中,在一个数据库连接下的操作,可以 ...

  3. Spring cloud的分布式事务解决方案(txlcn)

    Spring cloud的分布式事务解决方案 一.分布式CAP定律 C:Consistency一致性 所有节点访问最新的数据副本. A:Availability 可用性 当一个节点宕机,不影响数据的读 ...

  4. 分布式事务解决方案,Seata的基本配置和使用

    文章目录 1. 分布式事务介绍 ①:本地事务 ②:分布式事务 ③:常见的分布式事务解决方案 3. 2PC与3PC ①:2PC与3PC的区别 3. Seata介绍 ①:Seata的三种角色 ②:Seat ...

  5. 常用的分布式事务解决方案

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 常用的分布式事务解决方案 凌澜星空 2018-03-11 14:44:55  75315   ...

  6. 分布式事务解决方案 - SpringCloud Alibaba Seata

    目录 github代码:GitHub - 18409489244/seata: 基于springcloud alibaba seata 的分布式事务demo 一.常见分布式事务解决方案 二.分布式事务 ...

  7. seata分布式事务解决方案

    下载地址:Releases · seata/seata · GitHub 一.什么是分布式事务 首先这是普通事务: 下面是分布式事务: 在微服务系统中,每个微服务应用都可能会有自己的数据库,它们首先需 ...

  8. 分布式事务解决方案实战

    目录 1.数据库事务ACID 2.什么是分布式事务 3.单体事务和分布式事务 3.1 传统单体架构事务 3.2 微服务或者多数据源分布式事务 4.分布式事务理论基础 4.1 CAP 4.2 BASE ...

  9. SpringCloud分布式事务解决方案 整合 TX-LCN分布式事务框架

    第一章 分布式事务介绍 一.什么是分布式事务 分布式事务是指事务的参与者.支持事务的服务器.资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上. 举个栗子: 电商系统中的订单系统与库存系统 ...

最新文章

  1. vb.net中的部分代码
  2. WebsocketWebSSH
  3. Swift - final关键字的介绍,以及使用场景
  4. java运行jar命令提示没有主清单属性
  5. 组策略链接顺序优先级
  6. 数学特级教师:数学除了做习题,我还他让他们看这十部纪录片!
  7. gns3中两个路由器分别连接主机然后分析ip数据转发报文arp协议_ARP协议在同网段及跨网段下的工作原理...
  8. 修改apache 2.4.6的MPM模式
  9. C++内置数组和array的比较
  10. 皮尔逊系数皮尔逊系数---K近算法之皮尔逊系数
  11. 怎么做 空间杜宾模型_利用STATA创建空间权重矩阵及空间杜宾模型计算命令
  12. 新能源车企骗补终结:实力说话淘汰赛开启
  13. 计算机图形学立方体旋转代码,Flash AS教程:旋转立方体
  14. u3d计算机获取键盘输入,Unity 中的键盘输入
  15. 高德地图的集成(简单至极)
  16. 信息提取(Information Extraction)
  17. java 正则校验经纬度格式
  18. charles安装证书流程
  19. 服务器 z盘 映射,小脚本:在终端上映射网络驱动器Z盘
  20. gitlab self-hosted server

热门文章

  1. QQ等级一览表,呵呵
  2. android手机安装时缺少google map api 的解决方法
  3. 无限火力聊天服务器断开,无限火力导致客户端崩溃玩家集体掉线!官方暗中修复未发补偿说明...
  4. tcp/ip卷一学习-乱记之概述
  5. winhex手工数据恢复教程-李林峰-专题视频课程
  6. Spine之六——纹理打包Texture packing
  7. 教资证件照分辨率怎么调?照片分辨率怎么修改?
  8. android气泡飞舞,泡泡向前冲攻略彩色泡泡漫天飞舞
  9. android textview图片,Android如何在TextView中显示图片
  10. vue3简单处理全屏