- Seata 是什么
- Seata术语
- Seata常见问题
- 用户文档
- 开发者指南
- 运维指南
- 博客文章
- Seata 基于改良版雪花算法的分布式UUID生成器分析
- Seata 新特性支持 undo_log 压缩
- ConcurrentHashMap 导致的 Seata 死锁问题
- Seata 应用侧启动过程剖析 注册中心与配置中心模块
- Seata 应用侧启动过程剖析 RM & TM 如何与 TC 建立连接
- Spring Cloud 集成 Seata 分布式事务 TCC 模式
- Seata 配置管理原理解析
- seata-golang 通信模型详解
- Seata 数据源代理解析
- 分布式事务 Seata 源码-Client 端启动流程
- Mac 下的 Seata Demo 环境搭建(AT模式)
- 分布式事务 Seata 源码 - Server 端启动流程
- 分布式事务如何实现?深入解读 Seata 的 XA 模式
- Seata 极简入门
- Seata config 模块源码分析
- 源码分析 Seata-XID 传递 Dubbo 篇
- Seata tcc 模块源码分析
- 通过 AOP 动态创建/关闭 Seata 分布式事务
- Seata core 模块源码分析
- Seata 动态配置订阅与降级实现原理
- Seata 配置中心实现原理
- Docker 部署 Seata 与 Nacos 整合
- Seata 分布式事务启用 Nacos 做配置中心
- 透过源码解决 Seata AT 模式整合 Mybatis-Plus 失去 MP 特性的问题
- SpringBoot+Dubbo+MybatisPlus 整合 seata 分布式事务
- Seata 客户端需要同时启动 RM 和 TM 吗?
- Seata AT 模式启动源码分析
- 基于 Seata Saga 设计更有弹性的金融应用
- 分布式事务 Seata 及其三种模式详解
- 分布式事务中间件 Seata 的设计原理
- Seata分布式Go Server正式开源-TaaS设计简介
- Seata(Fescar)分布式事务 整合 Spring Cloud
- Fescar 与 Spring Cloud 集成源码深度剖析
- 深度剖析一站式分布式事务方案Seata-Server
- TCC适用模型与适用场景分析
- TCC 理论及设计实现指南介绍
- 如何使用Seata保证Dubbo微服务间的一致性
- Fescar分布式事务原理解析探秘
- MT 模式
Seata 常见问题
Q: 1.Seata 目前可以用于生产环境吗?
A: 0.4.2 版本之后就可以上生产环境,欢迎已经在使用的企业参与此 issue: who's using Seata
Q: 2.Seata 目前支持高可用吗?
A: 0.6 版本开始支持,tc 使用 db 模式共享全局事务会话信息,注册中心使用非 file 的 seata 支持的第三方注册中心
Q: 3.undo_log 表 log_status=1 的记录是做什么用的?
A:
- 场景 : 分支事务 a 注册 TC 后,a 的本地事务提交前发生了全局事务回滚
- 后果 : 全局事务回滚成功,a 资源被占用掉,产生了资源悬挂问题
- 防悬挂措施: a 回滚时发现回滚 undo 还未插入,则插入一条 log_status=1 的 undo 记录,a 本地事务(业务写操作 sql 和对应 undo 为一个本地事务)提交时会因为 undo 表唯一索引冲突而提交失败。
Q: 4.怎么使用 Seata 框架,来保证事务的隔离性?
A: 因 seata 一阶段本地事务已提交,为防止其他事务脏读脏写需要加强隔离。
- 脏读 select 语句加 for update,代理方法增加@GlobalLock+@Transactional 或@GlobalTransaction
- 脏写 必须使用@GlobalTransaction
注:如果你查询的业务的接口没有 GlobalTransactional 包裹,也就是这个方法上压根没有分布式事务的需求,这时你可以在方法上标注@GlobalLock+@Transactional 注解,并且在查询语句上加 for update。 如果你查询的接口在事务链路上外层有 GlobalTransactional 注解,那么你查询的语句只要加 for update 就行。设计这个注解的原因是在没有这个注解之前,需要查询分布式事务读已提交的数据,但业务本身不需要分布式事务。 若使用 GlobalTransactional 注解就会增加一些没用的额外的 rpc 开销比如 begin 返回 xid,提交事务等。GlobalLock 简化了 rpc 过程,使其做到更高的性能。
Q: 5.脏数据回滚失败如何处理?
A:
- 脏数据需手动处理,根据日志提示修正数据或者将对应 undo 删除(可自定义实现 FailureHandler 做邮件通知或其他)
- 关闭回滚时 undo 镜像校验,不推荐该方案。
注:建议事前做好隔离保证无脏数据
Q: 6.为什么分支事务注册时, 全局事务状态不是 begin?
A:
- 异常:Could not register branch into global session xid = status = Rollbacked(还有 Rollbacking、AsyncCommitting 等等二阶段状态) while expecting Begin
- 描述:分支事务注册时,全局事务状态需是一阶段状态 begin,非 begin 不允许注册。属于 seata 框架层面正常的处理,用户可以从自身业务层面解决。
- 出现场景(可继续补充)
1. 分支事务是异步,全局事务无法感知它的执行进度,全局事务已进入二阶段,该异步分支才来注册
2. 服务 a rpc 服务 b 超时(dubbo、feign 等默认 1 秒超时),a 上抛异常给 tm,tm 通知 tc 回滚,但是 b 还是收到了请求(网络延迟或 rpc 框架重试),然后去 tc 注册时发现全局事务已在回滚
3. tc 感知全局事务超时(@GlobalTransactional(timeoutMills = 默认 60 秒)),主动变更状态并通知各分支事务回滚,此时有新的分支事务来注册
Q: 7.Nacos 作为 Seata 配置中心时,项目启动报错找不到服务。如何排查,如何处理?
A: 异常:io.seata.common.exception.FrameworkException: can not register RM,err:can not connect to services-server.
- 查看 nacos 配置列表,seata 配置是否已经导入成功
- 查看 nacos 服务列表,serverAddr 是否已经注册成功
- 检查 client 端的 registry.conf 里面的 namespace,registry.nacos.namespace 和 config.nacos.namespace 填入 nacos 的命名空间 ID,默认"",server 端和 client 端对应,namespace 为 public 是 nacos 的一个保留控件,如果您需要创建自己的 namespace,最好不要和 public 重名,以一个实际业务场景有具体语义的名字来命名
- nacos 上服务列表,serverAddr 地址对应 ip 地址应为 seata 启动指定 ip 地址,如:sh seata-server.sh -p 8091 -h 122.51.204.197 -m file
- 查看 seata/conf/nacos-config.txt 事务分组 service.vgroupMapping.trade_group=default 配置与项目分组配置名称是否一致
- telnet ip 端口 查看端口是都开放,以及防火墙状态
注:1.080 版本启动指定 ip 问题,出现异常 Exception in thread "main" java.lang.RuntimeException: java.net.BindException: Cannot assign request address,请升级到 081 以上版本
2.项目使用 jdk13,启动出现
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
如环境为 sh,替换脚本中最后一段:
exec "$JAVACMD" $JAVA_OPTS -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k -XX:SurvivorRatio=10 -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=1024m -XX:-OmitStackTraceInFastThrow -XX:-UseAdaptiveSizePolicy -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath="$BASEDIR"/logs/java_heapdump.hprof -XX:+DisableExplicitGC -XX:+CMSParallelRemarkEnabled -XX:+
UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75 -verbose:gc -Dio.netty.leakDetectionLevel=advanced \
-classpath "$CLASSPATH" \
-Dapp.name="seata-server" \
-Dapp.pid="$$" \
-Dapp.repo="$REPO" \
-Dapp.home="$BASEDIR" \
-Dbasedir="$BASEDIR" \
io.seata.server.Server \
"$@"
Q: 8.Eureka 做注册中心,TC 高可用时,如何在 TC 端覆盖 Eureka 属性?
A: 在 seata\conf 目录下新增 eureka-client.properties 文件,添加要覆盖的 Eureka 属性即可。
例如,要覆盖 eureka.instance.lease-renewal-interval-in-seconds 和 eureka.instance.lease-expiration-duration-in-seconds,添加如下内容:
eureka.lease.renewalInterval=1
eureka.lease.duration=2
属性前缀为 eureka,其后的属性名可以参考类 com.netflix.appinfo.PropertyBasedInstanceConfigConstants,也可研究 seata 源码中的 discovery 模块的 seata-discovery-eureka 工程
Q: 9.发生下面异常是啥原因? java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.jsontype.TypeSerializer.typeId(Ljava/lang/Object;Lcom/fasterxml/jackson/core/JsonToken;)?
A: undolog 序列化配置为 jackson 时,jackson 版本需要为 2.9.9+
Q: 10.为什么 mybatis 没有返回自增 ID?
A: 方案 1.需要修改 mybatis 的配置: 在 @Options(useGeneratedKeys = true, keyProperty = "id")
或者在 xml 中指定 useGeneratedKeys 和 keyProperty 属性
方案 2.删除 undo_log 表的 id 字段
Q: 11.io.seata.codec.protobuf.generated 不存在,导致 seata server 启动不了?
A: 本地执行下: ./mvnw clean install -DskipTests=true
(Mac,Linux) 或 mvnw.cmd clean install -DskipTests=true
(Win), 参考 issues/2438 ,相关代码在 0.8.1 已经移除。
Q: 12.TC 如何使用 mysql8?
A: 1.修改 file.conf 的驱动配置 store.db.driver-class-name; 2.lib 目录下删除 mysql5 驱动,添加 mysql8 驱动
ps: oracle 同理;1.2.0 支持 mysql 驱动多版本隔离,无需再添加驱动
Q: 13.支持多主键?
A: 暂时只支持 mysql,其他类型数据库建议先建一列自增 id 主键,原复合主键改为唯一键来规避下
Q: 14.使用 HikariDataSource 报错如何解决?
A:
异常 1:ClassCastException: com.sun.proxy.$Proxy153 cannot be cast to com.zaxxer.hikari.HikariDataSource
原因: 自动代理时,实例类型转换错误,注入的是$Proxy153 实例,不是 HikariDataSource 的本身或子类实例。
解决: seata 自动代理数据源功能使用 jdk proxy, 对 DataSource 进行代理,生成的代理类 extends Proxy implements DataSource, 接收方可改成 DataSource 接收实现。
1.1.0 将同时支持 jdk proxy 和 cglib,届时该问题还可切换 cglib 解决。
Q: 15.是否可以不使用 conf 类型配置文件,直接将配置写入 application.properties?
A: 目前 seata-all 是需要使用 conf 类型配置文件,后续会支持 properties 和 yml 类型文件。当前可以在项目中依赖 seata-spring-boot-starter,然后将配置项写入到 application .properties 这样可以不使用 conf 类型文件。
Q: 16.如何自己修改源码后打包 seata-server?
A:
1. 删除 distribution 模块的 bin、conf 和 lib 目录。
2. ./mvnw clean install -DskipTests=true(Mac,Linux) 或 mvnw.cmd clean install -DskipTests=true(Win) -P release-seata。
3. 在 distribution 模块的 target 目录下解压相应的压缩包即可。
Q:17.Seata 支持哪些 RPC 框架?
A:
- AT 模式支持 Dubbo、Spring Cloud、Motan、gRPC 和 sofa-RPC。
- TCC 模式支持 Dubbo、Spring Cloud 和 sofa-RPC。
Q:18. java.lang.NoSuchMethodError: com.alibaba.druid.sql.ast.statement .SQLSelect.getFirstQueueBlockLcom/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock;
A:需要将 druid 的依赖版本升级至 1.1.12+ 版本,Seata 内部默认依赖的版本是 1.1.12(provided)。
Q:19. apache-dubbo 2.7.0 出现 NoSuchMethodError ?
A:由于 apache-dubbo 在加载 Filter 时,会将 alibaba-dubbo 的 filter 一并加载且 2.7.0 版本 com.alibaba.dubbo.rpc.Invoker 中Result invoke(org.apache.dubbo.rpc.Invocation invocation) throws RpcException;
误使用了 org.apache.dubbo.rpc.Invocation 来入参(2.7.1 修复),导致出现
java.lang.NoSuchMethodError: com.alibaba.dubbo.rpc.Invoker.invoke(Lcom/alibaba/dubbo/rpc/Invocation;)Lcom/alibaba/dubbo/rpc/Result;
所以请升级 dubbo 到 2.7.1 及以上,保证兼容.本身是 alibaba-dubbo 可放心使用,alibaba-dubbo 并不包含 apache-dubbo 的包。
参考链接: issue , PR
Q:20. 使用 AT 模式需要的注意事项有哪些 ?
A:
- 必须使用代理数据源,有 3 种形式可以代理数据源:
- 依赖 seata-spring-boot-starter 时,自动代理数据源,无需额外处理。
- 依赖 seata-all 时,使用 @EnableAutoDataSourceProxy (since 1.1.0) 注解,注解参数可选择 jdk 代理或者 cglib 代理。
- 依赖 seata-all 时,也可以手动使用 DatasourceProxy 来包装 DataSource。
- 配置 GlobalTransactionScanner,使用 seata-all 时需要手动配置,使用 seata-spring-boot-starter 时无需额外处理。
- 业务表中必须包含单列主键,若存在复合主键,请参考问题 13 。
- 每个业务库中必须包含 undo_log 表,若与分库分表组件联用,分库不分表。
- 跨微服务链路的事务需要对相应 RPC 框架支持,目前 seata-all 中已经支持:Apache Dubbo、Alibaba Dubbo、sofa-RPC、Motan、gRpc、httpClient,对于 Spring Cloud 的支持,请大家引用 spring-cloud-alibaba-seata。其他自研框架、异步模型、消息消费事务模型请结合 API 自行支持。
- 目前 AT 模式支持的数据库有:MySQL、Oracle、PostgreSQL 和 TiDB。
- 使用注解开启分布式事务时,若默认服务 provider 端加入 consumer 端的事务,provider 可不标注注解。但是,provider 同样需要相应的依赖和配置,仅可省略注解。
- 使用注解开启分布式事务时,若要求事务回滚,必须将异常抛出到事务的发起方,被事务发起方的 @GlobalTransactional 注解感知到。provide 直接抛出异常 或 定义错误码由 consumer 判断再抛出异常。
Q:21. win 系统使用同步脚本进行同步配置时为什么属性会多一个空行?
A:目前是知道为什么配置会有个\r,大概是因为这个文件你是在 win 编写的,所以有换行符为\r\n,然后你用 git bash 执行(这个可认为是 linux)只认\n 换行,所以就多了\r 解决办法目前有两个: 1、sed -i ""s/\r//"" config.txt 2、vim 进入文本,再用命令 set fileformat=unix(亲测可用)
Q:22. AT 模式和 Spring @Transactional 注解连用时需要注意什么 ?
A:
@Transactional 可与 DataSourceTransactionManager 和 JTATransactionManager 连用分别表示本地事务和 XA 分布式事务,大家常用的是与本地事务结合。当与本地事务结合时,@Transactional 和@GlobalTransaction 连用,@Transactional 只能位于标注在@GlobalTransaction 的同一方法层次或者位于@GlobalTransaction 标注方法的内层。这里分布式事务的概念要大于本地事务,若将 @Transactional 标注在外层会导致分布式事务空提交,当@Transactional 对应的 connection 提交时会报全局事务正在提交或者全局事务的 xid 不存在。
Q:23. Spring boot 1.5.x 出现 jackson 相关 NoClassDefFoundException ?
A:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.ObjectMapper
目前发现在 Spring Boot 1.5.x 版本中原始引入的 jackson 版本过低,会导致 Seata 依赖 jackson 的新特性找不到,Seata 要求 jackson 版本 2.9.9+,但是使用 jackson 2.9.9+ 版本会导致 Spring Boot 中使用的 jackson API 找不到,也就是 jackson 本身的向前兼容性存在问题。因此,建议大家将 Seata 的序列化方式切换到非 jackson 序列化方式,比如 kryo,配置项为 client.undo.logSerialization = "kryo"
Q:24. SpringCloud xid 无法传递 ?
A:
1.首先确保你引入了 spring-cloud-alibaba-seata 的依赖.
2.如果 xid 还无法传递,请确认你是否实现了 WebMvcConfigurer,如果是,请参考 com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration#addInterceptors 的方法.把 SeataHandlerInterceptor 加入到你的拦截链路中.
Q:25. 使用 mybatis-plus 动态数据源组件后 undolog 无法删除 ?
A:dynamic-datasource-spring-boot-starter 组件内部开启 seata 后会自动使用 DataSourceProxy 来包装 DataSource,所以需要以下方式来保持兼容
1.如果你引入的是 seata-all,请不要使用 @EnableAutoDataSourceProxy 注解。
2.如果你引入的是 seata-spring-boot-starter 请关闭自动代理
seata:
enable-auto-data-source-proxy: false
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论