常見問題
本文主要介紹在操作分布式事務過程中的常見問題。
SOFAStack 是否可以部署在虛擬機、物理機上?
可以,SOFAStack 部署支持物理機、虛機機 VM。
SOFAStack 當前是否只支持阿里云飛天 ACK?
SOFAStack 部署支持多云異構、目前支持華為云、開源 Openstack 等。
分布式事務支持哪些數(shù)據(jù)庫?
目前支持 MySQL、Oracle、RDS MySQL、PostgreSQL 等主流數(shù)據(jù)庫。
分布式事務是否支持 VPC 私有云部署?
支持,如有需要,請咨詢售后技術支持。
在分布式事務服務掛掉的情況下,事務是否能正常回滾?
分布式事務的服務端會記錄下事務的狀態(tài)并持久化,即使服務掛掉,在服務重新啟動后,事務仍然能夠正常回滾。
建表時,是否可以使用 SQL 的關鍵字作為列的名稱?
不可以,建表時列名不能使用 SQL 的關鍵字,如 DESC、TABLE 等。
接入分布式事務時需要依賴什么?
如果您使用的是數(shù)據(jù)訪問代理中的分布式事務,因為數(shù)據(jù)訪問代理和分布式事務已經(jīng)深度集成,部署時是不需要任何依賴的,僅需一行事務開啟 SQL 語句就能開啟事務。
如果您是基于 SDK 方式使用分布式事務,就需要在引入的分布式事務 SDK 的 pom.xml
中加入相關依賴,詳見開發(fā)指南。
開通分布式事務之后,SOFABoot、Dubbo、消息隊列、數(shù)據(jù)訪問代理、RDS、MySQL、Oracle、OceanBase 能否都加入分布式事務?
可以,分布式事務已經(jīng)打通了 SOFABoot、Dubbo、消息隊列、數(shù)據(jù)訪問代理、RDS、MySQL、Oracle、OceanBase 之間的事務。
服務 A 調用服務 B,服務 A 上加了分布式事務并開啟事務注解,服務 B 沒有注解,那么 A 和 B 是否在同一個分布式事務中?
服務 A 和 B 在一個事務中。只要服務 A 的函數(shù)上加入了分布式事務的注解,那么服務 A 注解函數(shù)下面所有的被調用的服務及其子調用的服務都會加入到這個服務 A 的事務中。
分布式事務是否支持多機房高可用?
分布式事務支持同城、異地多活,高可用。當一個機房由于斷網(wǎng)、停電等突發(fā)狀況造成全機房不可用時,分布式事務能切換到備用機房繼續(xù)提供服務。
如何判斷分布式事務 SDK 與事務云服務的網(wǎng)絡連接是否正常?
在事務云服務上執(zhí)行 netstat -an | grep 14200
,看是否存在 TCP 連接。如果存在 TCP 連接,說明事務云服務啟動正常;否則說明事務云服務已宕機或者網(wǎng)絡已中斷。
分布式事務 SDK 與事務云服務網(wǎng)絡連接正常,但是通信失敗,是什么原因?
TCP 連接正常,說明事務云服務啟動正常。
分布式事務 SDK 與事務云服務通信返回失敗消息,說明 SDK 發(fā)送給事務云服務的消息違反某些約束條件,可以根據(jù)事務 ID 在 dtx-rpc.log
中查詢事務云服務返回的具體失敗信息。
如何查看分布式事務的日志?
分布式事務的事務日志存放路徑為 ${user.home}/logs/dtx-xxx.log
,其中 ${user.home}
為啟動分布式事務 SDK 的用戶賬戶的根目錄。不同的日志文件,打印的日志內容也不同,具體如下:
dtx-client.log
打印 SDK 啟動和所有事務執(zhí)行情況的日志。dtx-rpc.log
打印 SDK 與分布式事務服務端的所有通信信息。dtx-parser.log
打印 SQL 語句語法解析日志。dtx-rm.log
打印所有參與者(TCC、FMT)的二階段執(zhí)行日志。dtx-datasource.log
打印 FMT 模式下的事務執(zhí)行日志。
查看日志時,可以按照分布式事務的事務 ID 去查看這個事務在該 SDK 都操作了哪些資源及其提交和回滾情況。
分布式事務 TCC @TwoPhaseBusinessAction 放到接口的實現(xiàn)類上是否有效?
沒有效果,不能放到實現(xiàn)類上,必須放在接口上。
public interface UserFacade{
@TwoPhaseBusinessAction(name ="sendMessage", commitMethod="commit", rollbackMethod ="cancel")
public boolean sendMessage(final BusinessActionContext businessActionContext,@BusinessActionContextParameter(paramName ="userId")String userId);
public boolean commit(final BusinessActionContext businessActionContext);
public boolean cancel(final BusinessActionContext businessActionContext);
}
如何傳遞參數(shù)給二階段方法 Commit/Cancel?
可以通過以下任一方式:
使用額外的存儲來記錄 txid 和業(yè)務數(shù)據(jù)的關系。
使用 BusinessActionContext 傳遞。
說明不能通過直接設置 BusinessActionContext 來傳遞,此種方式不會被保存。需要使用@BusinessActionContextParameter 注解。
DTX 發(fā)起方和參與方同屬一個應用,能否不使用 RPC?
可以在參與方接口上添加 @InjvmRemoting
注解,這樣發(fā)起方去調用參與方就是 JVM 內調用。而且這種情況下,DTX 服務端來遠程調用二階段方法也不會通過注冊中心,而是 DTX 自閉環(huán)尋址處理。
以 TCC 模式為例:
// 注解InjvmRemoting用于當發(fā)起方與參與方是同一個應用,也就是說參與方不需要被其他應用通過注冊中心尋址來進行RPC調用
@InjvmRemoting
public interface AcctDepositTccService{
/**
* <p>
* 貸記記賬接口 TCC模式
* </p>
*
* <p>
* 結合賬戶的余額方向來對賬戶的資金進行流入 or 流出操作
* </p>
*
* @param accountTransRequest 請求對象參數(shù),詳情請見{@link AccountTransRequest}
* @param businessActionContext dtx框架中請求的上下文信息,框架級別參數(shù),調用者不需傳遞,由dtx自動注入。
* @return AccountTransResult 交易處理結果
*/
@TwoPhaseBusinessAction(name ="creditAction", commitMethod ="commit", rollbackMethod ="rollback", antiSuspend =true)
public AccountTransResult credit(AccountTransRequest accountTransRequest,@ShardingKeyString accountNo,
BusinessActionContext businessActionContext);
/**
* 二階段提交
*
* @param businessActionContext xts上下文
* @return TwoPhaseResult#isSuccess() 是否成功,true-成功,false-失敗
*/
public boolean commit(BusinessActionContext businessActionContext);
/**
* 二階段回滾
*
* @param businessActionContext xts上下文
* @return TwoPhaseResult#isSuccess() 是否成功,true-成功,false-失敗
*/
public boolean rollback(BusinessActionContext businessActionContext);
}
DTX 創(chuàng)建事務分支時出現(xiàn)“Data too long for column ‘log_Info’”報錯
問題現(xiàn)象
DTX 創(chuàng)建事務分支報錯:Data too long for column ‘log_Info’。
問題原因
業(yè)務代碼更新的數(shù)據(jù)庫內容太多,超過了 log_info
的最大長度。
解決方案
需要優(yōu)化業(yè)務代碼,最好是業(yè)務優(yōu)化 SQL 邏輯,或者修改表中該字段的類型,比如 LONGBLOB
。
客戶端啟動分布式事務時出現(xiàn)“invoke dtx-server to create Activity failed”報錯
問題現(xiàn)象
客戶端啟動 DTX 失敗,報錯:DTX-037: invoke dtx-server to create Activity failed.
在 DTX server 端,實際錯誤碼為
error code: 101
,如下圖所示:在控制臺轉換字符編碼,可以看到實際的錯誤是:數(shù)據(jù)源最大連接數(shù)已滿,并且在超時時間范圍內沒有新的連接釋放,如下圖所示:
問題原因
DTX server 與 DTX DB 的數(shù)據(jù)庫連接數(shù)設置成了 2。
解決方案
如有需要,您可以咨詢售后技術支持。
事務進行過程中發(fā)生“DTX-036 activity record is not exist”報錯
問題現(xiàn)象
報錯:DTX-036 activity record is not exist。
詳細的錯誤信息下圖所示:
問題原因
根據(jù)上圖所示的錯誤信息,事務的請求者和事務的參與者的 instance ID 不匹配。例如事務 ds:jdbc:mysql://10.10.29.212:XXXX
配置錯誤,instance ID 配置成了 00000X
,使得事務請求方 instance ID = 00000X
。而事務的真實 instance ID 其實是 8PCDDO6YXXXX
。
解決方案
排查事務的參與方的 application.properties
配置,確保事務的請求者和事務的參與者的 instance ID 匹配。
DTX 2.2.1 版本,支持 Saga 模式嗎?
不支持,如有需要,請咨詢售后科技支持。
分布式事務二階段請求未執(zhí)行
問題現(xiàn)象
使用時出現(xiàn)報錯:“com.alipay.dtx.common.exception.DtxException:DTX-032:TCC prepare menthod must have a parameter who's type isBusinessActionContext”。
啟動時出現(xiàn)報錯:“DTX-302:initdtx-servers' tcp long-conections failed”。
問題原因
dtxserver 未發(fā)起二階段請求。
客戶端收到二階段請求但執(zhí)行失敗。
解決方案
針對以上兩種情況有兩種解決方案:
dtxserver 未發(fā)起二階段請求
登錄 dtxserver 機器,在
/home/admin/logs/dtxserver/dtx-remote.log
日志中搜索事務 ID,查找該異常事務相關信息。若未找到該異常事務的恢復日志,說明該事務的二階段任務未開始執(zhí)行,可能是未正常執(zhí)行或出現(xiàn)事務積壓,需重新發(fā)起事務。
若找到該異常事務的恢復日志,說明執(zhí)行過程出錯,在
dtx-remote.log
和commen-error.log
中查看出錯原因,在改進后重新發(fā)起任務。
客戶端收到二階段請求但執(zhí)行失敗
查詢客戶端是否收到二階段的請求。
在客戶端
/home/admin/logs/dtx/dtx-rpc.log
日志中搜索事務 ID,若找到“BranchCommitRequest”或“BranchrollbackRequest”的消息,說明客戶端收到了二階段請求。查看二階段請求是否成功執(zhí)行。
在
/home/admin/logs/dtx/dtx-rm.log
日志中搜索事務 ID,若找到“branch commit result”或“branch rollback result”相關內容,且返回結果為 true ,則表示執(zhí)行成功;反之,執(zhí)行失敗,根據(jù)報錯信息排查執(zhí)行失敗的原因,在改進后回滾事務重新執(zhí)行。