常见问题
1.Seata 目前可以用于生产环境吗?2.Seata 目前支持高可用吗?
3.undo_log 表 log_status=1 的记录是做什么用的?
4.怎么使用 Seata 框架,来保证事务的隔离性?
5.脏数据回滚失败如何处理?
6.为什么分支事务注册时, 全局事务状态不是 begin?
7.Nacos 作为 Seata 配置中心时,项目启动报错找不到服务。如何排查,如何处理?
8.Eureka 做注册中心,TC 高可用时,如何在 TC 端覆盖 Eureka 属性?
9.java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.jsontype.TypeSerializer.typeId(Ljava/lang/Object;Lcom/fasterxml/jackson/core/JsonToken;)?
10.为什么 mybatis 没有返回自增 ID?
11.io.seata.codec.protobuf.generated 不存在,导致 seata server 启动不了?
12.TC 如何使用 mysql8?
13.支持多主键?
14.使用 HikariDataSource 报错如何解决 ?
15.是否可以不使用 conf 类型配置文件,直接将配置写入 application.properties?
16.如何自己修改源码后打包 seata-server ?
17. Seata 支持哪些 RPC 框架 ?
18. java.lang.NoSuchMethodError: com.alibaba.druid.sql.ast.statement .SQLSelect.getFirstQueueBlockLcom/alibaba/druid/sql/ast/statement/SQLSelectQueryBlock;
19. apache-dubbo 2.7.0 出现 NoSuchMethodError ?
20. 使用 AT 模式需要的注意事项有哪些 ?
21. win 系统使用同步脚本进行同步配置时为什么属性会多一个空行?
22. AT 模式和 Spring @Transactional 注解连用时需要注意什么 ?
23. Spring boot 1.5.x 出现 jackson 相关 NoClassDefFoundException ?
24. SpringCloud xid 无法传递 ?
25. 使用动态数据源后的常见问题 ?
26. Could not found global transaction xid = %s, may be has finished.
27. TC 报这个错:An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception 是什么原因?
28. 数据库开启自动更新时 间戳导致脏数据无法回滚?
29. 还没到全局事务超时时间就出现了 timeoutrollcking?
30. Seata 现阶段支持的分库分表解决方案?
31. Seata 使用注册中心注册的地址有什么限制?
32. seata-server cannot be started due to Unrecognized VM option 'CMSParallelRemarkEnabled' Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.导致 seata-server 无法启动?
33. Seata 的 SQL 支持范围?
34. Seata 的 JDK 版本要求?
35. Oracle 的 NUMBER 长度超过 19 之后,实体使用 Long 映射,导致获取不到行信息,导致 undo_log 无法插入,也无法回滚?
36. 怎么处理 io.seata.rm.datasource.exec.LockConflictException: get global lock fail ?
37. 为什么在客户端在编译和运行时 JDK 版本都是 1.8 的情况下还会出现 java.nio.ByteBuffer.flip()Ljava/nio/ByteBuffer 错误 ?
38. 为什么在使用 Apple 的 M1 芯片下载 maven 依赖时,无法下载依赖
com.google.protobuf:protoc:exe:3.3.0
?
39. 1.4.2 及以下版本回滚时抛出 Cannot construct instance of
java.time.LocalDateTime
40. Seata-Server 使用 DB 作为存储模式时,有哪些注意事项?
41. Oracle 使用 timestamp 字段类型回滚失败?
42. 抛出异常后事务未回滚?
43. 怎么处理@FeignClient 注解 url 不起效,提示 Load balancer does not have available server for client 错误?
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 或@GlobalTransactional
- 脏写 必须使用@GlobalTransactional
注:如果你查询的业务的接口没有@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,oracle,pgsql,mariadb,其他类型数据库建议先建一列自增 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 目录下解压相应的压缩包即可。
4. seata-1.5之后(最新develop分支)的打包命令:mvn -Prelease-seata -Dmaven.test.skip=true clean install -U
Q: 17.Seata 支持哪些 RPC 框架?
A:
目前支持 Dubbo、Spring Cloud、Motan、gRPC、sofa-RPC、EDAS-HSF 和 bRPC 框架。
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 和@GlobalTransactional 连用,@Transactional 只能位于标注在@GlobalTransactional 的同一方法层次或者位于@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