全部产品

常见问题

更新时间:2020-08-28 19:11:36

分布式事务的常见问题如下:


分布式事务是否支持 VPC 私有云部署?

支持,如有需要,请提交工单申请,或者咨询金融科技售后。


在分布式事务服务挂掉的情况下,事务是否能正常回滚?

分布式事务的服务端会记录下事务的状态并持久化,即使服务挂掉,在服务重新启动后,事务仍然能够正常回滚。


建表时,是否可以使用 SQL 的关键字作为列的名称?

不可以,建表时列名不能使用 SQL 的关键字,如 DESC、TABLE 等。


接入分布式事务时需要依赖什么?

如果您使用的是数据访问代理中的分布式事务,因为数据访问代理和分布式事务已经深度集成,部署时是不需要任何依赖的,仅需一行事务开启 SQL 语句就能开启事务。

如果您是基于 SDK 方式使用分布式事务,就需要在引入的分布式事务 SDK 的 pom.xml 中加入相关依赖,详见开发指南。


开通分布式事务之后,SOFABoot、Dubbo、消息队列、数据访问代理、RDS、MySQL、Oracle、OceanBase 能否都加入分布式事务?

可以,分布式事务已经打通了 SOFABoot、Dubbo、消息队列、数据访问代理、RDS、MySQL、Oracle、OceanBase 之间的事务。


服务 A 调用服务 B,服务 A 上加了分布式事务并开启事务注解,服务 B 没有注解,那么 A 和 B 是否在同一个分布式事务中?

服务 A 和 B 在一个事务中。只要服务 A 的函数上加入了分布式事务的注解,那么服务 A 注解函数下面所有的被调用的服务及其子调用的服务都会加入到这个服务 A 的事务中。


分布式事务是否支持多机房高可用?

分布式事务支持同城、异地多活,高可用。当一个机房由于断网、停电等突发状况造成全机房不可用时,分布式事务能切换到备用机房继续提供服务。


如何判断分布式事务 SDK 与事务云服务的网络连接是否正常?

在事务云服务上执行 netstat -an | grep 14200,看是否存在 TCP 连接。如果存在 TCP 连接,说明事务云服务启动正常;否则说明事务云服务已宕机或者网络已中断。


分布式事务 SDK 与事务云服务网络连接正常,但是通信失败,是什么原因?

TCP 连接正常,说明事务云服务启动正常。

分布式事务 SDK 与事务云服务通信返回失败消息,说明 SDK 发送给事务云服务的消息违反某些约束条件,可以根据事务 ID 在 dtx-rpc.log 中查询事务云服务返回的具体失败信息。


如何查看分布式事务的日志?

分布式事务的事务日志存放路径为 ${user.home}/logs/dtx-xxx.log,其中 ${user.home} 为启动分布式事务 SDK 的用户账户的根目录。不同的日志文件,打印的日志内容也不同,具体如下:

  • dtx-client.log 打印 SDK 启动和所有事务执行情况的日志。
  • dtx-rpc.log 打印 SDK 与分布式事务服务端的所有通信信息。
  • dtx-parser.log 打印 SQL 语句语法解析日志。
  • dtx-rm.log 打印所有参与者(TCC、FMT)的二阶段执行日志。
  • dtx-datasource.log 打印 FMT 模式下的事务执行日志。

查看日志时,可以按照分布式事务的事务 ID 去查看这个事务在该 SDK 都操作了哪些资源及其提交和回滚情况。


DTX server 如何配置异库或同库模式?

配置 com.alipay.dtx.model 参数。REMOTE 是异库,LOCAL 是同库。—-

分布式事务 TCC @TwoPhaseBusinessAction 放到接口的实现类上是否有效?

没有效果,不能放到实现类上,必须放在接口上。

  1. public interface UserFacade {
  2. @TwoPhaseBusinessAction(name = "sendMessage", commitMethod="commit", rollbackMethod = "cancel")
  3. public boolean sendMessage(final BusinessActionContext businessActionContext, @BusinessActionContextP
  4. arameter(paramName = "userId") String userId);
  5. public boolean commit(final BusinessActionContext businessActionContext);
  6. public boolean cancel(final BusinessActionContext businessActionContext);
  7. }

如何传递参数给二阶段方法 Commit/Cancel?

可以通过以下任一方式:

  • 使用额外的存储来记录 txid 和业务数据的关系。
  • 使用 BusinessActionContext 传递。

    注意:不能通过直接设置 BusinessActionContext 来传递,此种方式不会被保存。需要使用@BusinessActionContextParameter 注解。


DTX 发起方和参与方同属一个应用,能否不使用 RPC?

可以在参与方接口上添加 @InjvmRemoting 注解,这样发起方去调用参与方就是 JVM 内调用。而且这种情况下,DTX 服务端来远程调用二阶段方法也不会通过注册中心,而是 DTX 自闭环寻址处理。

以 TCC 模式为例:

  1. // 注解InjvmRemoting用于当发起方与参与方是同一个应用,也就是说参与方不需要被其他应用通过注册中心寻址来进行RPC调用
  2. @InjvmRemoting
  3. public interface AcctDepositTccService {
  4. /**
  5. * <p>
  6. * 贷记记账接口 TCC模式
  7. * </p>
  8. *
  9. * <p>
  10. * 结合账户的余额方向来对账户的资金进行流入 or 流出操作
  11. * </p>
  12. *
  13. * @param accountTransRequest 请求对象参数,详情请见{@link AccountTransRequest}
  14. * @param businessActionContext dtx框架中请求的上下文信息,框架级别参数,调用者不需传递,由dtx自动注入。
  15. * @return AccountTransResult 交易处理结果
  16. */
  17. @TwoPhaseBusinessAction(name = "creditAction", commitMethod = "commit", rollbackMethod = "rollback", antiSuspend = true)
  18. public AccountTransResult credit(AccountTransRequest accountTransRequest, @ShardingKey String accountNo,
  19. BusinessActionContext businessActionContext);
  20. /**
  21. * 二阶段提交
  22. *
  23. * @param businessActionContext xts上下文
  24. * @return TwoPhaseResult#isSuccess() 是否成功,true-成功,false-失败
  25. */
  26. public boolean commit(BusinessActionContext businessActionContext);
  27. /**
  28. * 二阶段回滚
  29. *
  30. * @param businessActionContext xts上下文
  31. * @return TwoPhaseResult#isSuccess() 是否成功,true-成功,false-失败
  32. */
  33. public boolean rollback(BusinessActionContext businessActionContext);
  34. }

Data too long for column ‘log_Info’

现象

DTX 创建事务分支报错:Data too long for column ‘log_Info’。

原因

业务代码更新的数据库内容太多,超过了 log_info 的最大长度。

解决方案

需要优化业务代码,最好是业务优化 SQL 逻辑,或者修改表中该字段的类型,比如 LONGBLOB


DTX-037: invoke dtx-server to create Activity failed

现象

  • 客户端启动 DTX 失败,报错:DTX-037: invoke dtx-server to create Activity failed.
  • 在 DTX server 端,实际错误码为 error code: 101,如下图所示:服务端信息
  • 在控制台转换字符编码,可以看到实际的错误是:数据源最大连接数已满,并且在超时时间范围内没有新的连接释放,如下图所示:控制台信息

原因

DTX server 与 DTX DB 的数据库连接数设置成了 2。

解决方案

可以在 dtx-config 数据库,dtx_recovery_ds 表里面,查看 db_conn_max 字段,并将两个表的 db_conn_max 修改为 20,然后重启 DTX server(一般为两台)。

说明

  • 旧版的 DTX server 默认为 2,新版的为 20。
  • DTX server 没有用 ZDAL,而是用的 dbcp 连接池。

DTX-036:activity record is not exist

现象

  • 报错:Dtx-036 activity record is not exist。
  • 详细的错误信息下图所示:dtx036

原因

根据上图所示的错误信息,事务的请求者和事务的参与者的 instanceId 不匹配。事务 ds:jdbc:mysql://10.10.29.212:2883 配置错误,instanceId 配置成了 000001,使得事务请求方 instanceId = 000001。而事务的真实 instanceId 其实是 8PCDDO6Y2OEV

解决方案

排查事务的参与方的 application.properties 配置,将 instanceId 更改为 8PCDDO6Y2OEV