Seata,阿里开源的分布式事务框架,多的我就不介绍了,了解详细介绍,请看官网。seata spring boot入门,可以看我上一篇博客《Spring boot微服务如何集成fescar解决分布式事务问题?》(fescar后来更名为seata)。

  本篇,将介绍,同时使用seata的tcc模式和at模式的一些问题。点击demo,可查看相关源代码。

第一个问题:数据源使用seata代理的数据源,同时使用TCC模式,将导致注册到TC的分支事务多一倍

  

  在上一篇博客中,我们说到,要让分支事务加入全局事务,需要分支事务rm获得全局事务的xid,所以我们通过feign将xid传递到下游的微服务。但是AT模式的rm在下游服务的代理数据源处,TCC模式的rm在上游服务的TccAction处做的代理。此时要解决分支事务重复注册的问题,在使用TCC模式的时候就不能把xid传递到下游服务,这样,下游服务数据源代理处判断到这个数据库操作不在全局事务中,就不会向TC注册。

  解决的办法:我们在feign header里加入一个标识,标志此请求是不是TCC模式的请求,如果是,则不将xid传递到下游服务。

@Component
public class RequestHeaderInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
boolean seataTransactionATMode = true;
if (attributes!=null) {
HttpServletRequest request = attributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) { Map<String, Collection<String>> resolvedHeaders = new CaseInsensitiveKeyMap<>();
resolvedHeaders.putAll(template.headers()); while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if (!resolvedHeaders.containsKey(name)) {
String values = request.getHeader(name);
List<String> headers = new ArrayList<String>();
headers.addAll(Arrays.asList(values));
resolvedHeaders.put(name, headers);
}
}
template.headers(null);
template.headers(resolvedHeaders);
}
}
Map<String, Collection<String>> headers = template.headers();
if(headers!=null){
Collection<String> values = headers.getOrDefault(SeataConstants.TRANSACTION_MODE_HEADER,null);
if (values==null) {
values = headers.getOrDefault(SeataConstants.TRANSACTION_MODE_HEADER.toLowerCase(),null);
}
if(values!=null&&values.contains("TCC")){
seataTransactionATMode = false;
}
}
if(seataTransactionATMode) {
String xid = RootContext.getXID();
if (StringUtils.isNotBlank(xid)) {
template.header(SeataConstants.XID_HEADER, xid);
}
}
}
}

使用tcc模式有一个点需要注意,

    @TwoPhaseBusinessAction(name = "CreateOrderTccAction" , commitMethod = "commit", rollbackMethod = "rollback")
public boolean prepare(BusinessActionContext actionContext, List<SoMaster> soMasters, @BusinessActionContextParameter(paramName = "SoSysNos") String soSysNos) throws BusinessException;

那就是BusinessActionContextParameter尽量使用简单类型,如果是复杂类型,在注册分支事务时会被序列化成json字符串,把上下文数据存到session。提交或者重试的时候,从actionContext获取参数的时候actionContext.getActionContext("your argument")返回的是个object对象,此对象是个jsonObject,无法直接转为复杂类型,需要tostring,再json反序列化。

第二个问题:在目前的undolog序列化协议中,数据库里bigint类型的数据,被序列化后,再在undo回滚时反序列化回object类型,真实的值类型变成了int型

{"branchId":2013531184,"sqlUndoLogs":[{"afterImage":{"rows":[{"fields":[{"keyType":"PrimaryKey","name":"sysno","type":-5,"value":1},{"keyType":"NULL","name":"available_qty","type":4,"value":999992},{"keyType":"NULL","name":"allocated_qty","type":4,"value":8}]}],"tableName":"inventory"},"beforeImage":{"rows":[{"fields":[{"keyType":"PrimaryKey","name":"sysno","type":-5,"value":1},{"keyType":"NULL","name":"available_qty","type":4,"value":999994},{"keyType":"NULL","name":"allocated_qty","type":4,"value":6}]}],"tableName":"inventory"},"sqlType":"UPDATE","tableName":"inventory"}],"xid":"172.16.4.137:8091:2013531176"}

如上,{"keyType":"PrimaryKey","name":"sysno","type":-5,"value":1},sysno,type -5表示这是一个bigint的类型,反序列化后,value的真正值类型是int型,这个问题可以参考issue 1139

在目前的版本0.6.1,已经支持TC的高可用吗,但这个bug还没有解决,如果使用类型判断去做转换来修复这个bug,预计会写很多if else。官方回复的解决办法是,他们会修改序列化的协议来解决这个bug。期待官方尽快修复这个bug。

分享一个seata demo,讲两个个问题的更多相关文章

  1. .Net Excel 导出图表Demo(柱状图,多标签页) .net工具类 分享一个简单的随机分红包的实现方式

    .Net Excel 导出图表Demo(柱状图,多标签页) 1 使用插件名称Epplus,多个Sheet页数据应用,Demo为柱状图(Epplus支持多种图表) 2 Epplus 的安装和引用 新建一 ...

  2. 【开源.NET】 分享一个前后端分离的轻量级内容管理框架

    开发框架要考虑的面太多了:安全.稳定.性能.效率.扩展.整洁,还要经得起实践的考验,从零开发一个可用的框架,是很耗时费神的工作.网上很多开源的框架,为何还要自己开发?我是基于以下两点: 没找到合适的: ...

  3. seata demo

    0. 介绍 2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案.Fes ...

  4. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  5. 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载

    一.分布式消息总线 在很多MIS项目之中都有这样的需求,需要一个及时.高效的的通知机制,即比如当使用者A完成了任务X,就需要立即告知使用者B任务X已经完成,在通常的情况下,开发人中都是在使用者B所使用 ...

  6. 分享一个漂亮的ASP.NET MVC界面框架

    本文分享一个插件化的界面框架,该框架提供了用户.角色.权限管理功能,也提供了插件的管理和插件中心.下图是该界面框架的样式(全部源码和原理介绍下一篇分享,推荐越多,源码放的越早,呵呵). 要使用该界面框 ...

  7. [Unity3D入门]分享一个自制的入门级游戏项目"坦克狙击手"

    [Unity3D入门]分享一个自制的入门级游戏项目"坦克狙击手" 我在学Unity3D,TankSniper(坦克狙击手)这个项目是用来练手的.游戏玩法来自这里(http://ww ...

  8. LeadTools Android 入门教学——运行第一个Android Demo

    LeadTools 有很多Windows平台下的Demo,非常全面,但是目前开发手机应用的趋势也越来越明显,LeadTools也给大家提供了10个Android的Demo,这篇文章将会教你如何运行第一 ...

  9. Git.Framework 框架随手记-- 分享一个"比较垃圾"的项目

    本文主要分享一个Git.Framework 开发的一个项目的部分源码,此项目代码"比较垃圾",所以请各位码农,码畜,码神,码圣勿喷!发此文只为记录工作问题以及分享问题! 一. 项目 ...

随机推荐

  1. ZROI17普及23-A.如烟题解--技巧枚举

    题目链接 因版权原因不予提供 分析 别看这是普及模拟赛,其实基本上是提高难度...像这题做NOIpT1的话也说的过去 有个很显然的暴力思路就是枚举c,a,b,时间复杂度\(O(N^3)\), 然后正解 ...

  2. ubantu18.04 配置nginx与uwsgi(前后端分离)

    ubantu18.04 配置nginx与uwsgi   一.首先先安装nginx静态服务 先更新 sudo apt-get update 1.安装gcc g++的依赖库 sudo apt-get in ...

  3. Eureka服务注册于发现之Client搭建

    Eureka在Server端的搭建已经有很多介绍的文章,同时也是学习Eureka的第一步. 搭建好注册中心后怎么进行服务注册和服务调用,是我们要讲的主要内容. 开发环境:IDEA2018.3+Spri ...

  4. [书籍翻译] 《JavaScript并发编程》第三章 使用Promises实现同步

    本文是我翻译<JavaScript Concurrency>书籍的第三章 使用Promises实现同步,该书主要以Promises.Generator.Web workers等技术来讲解J ...

  5. bash shell的ANSI控制

    格式: echo -e "\033[字背景颜色;字体颜色m字符串\033[0m" 例如:  echo -e "\033[41;36m something here \03 ...

  6. 二零一八阿里p7笔试116题

    1. junit用法,before,beforeClass,after, afterClass的执行顺序 2. 分布式锁 3. nginx的请求转发算法,如何配置根据权重转发 4. 用hashmap实 ...

  7. Django drf:认证及组件、token、局部钩子源码分析

    一.drf认证功能 二.token讲解 三.局部钩子源码分析 一.drf认证功能 1.认证简介: 只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录则不能查 ...

  8. FreeRTOS时间管理

    延时函数 vTaskDelay() 相对延时函数,在文件task.c中定义的,要使用的话宏INCLUDE_vTaskDelay必须设置为1: void vTaskDelay( const TickTy ...

  9. Oracle中统计block空闲情况的一个SQL语句

    此SQL来自网络,地址见具体内容.介绍表空间回收原理的文章参考此链接: https://oracle-base.com/articles/misc/reclaiming-unused-space#sh ...

  10. Hadoop的简单了解与安装

    hadoop 一, Hadoop  分布式 简介Hadoop  是分布式的系统架构,是  Apache  基金会顶级金牌项目 分布式是什么?学会用大数据的思想来看待和解决问题 思 想很重要 1-1 . ...