diff --git a/.github/workflows/compatibility.yml b/.github/workflows/compatibility.yml index e598e4b61..1cdba8a2a 100644 --- a/.github/workflows/compatibility.yml +++ b/.github/workflows/compatibility.yml @@ -14,7 +14,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: "1.21.0" + go-version: "1.23.0" - name: Checkout Client-Go uses: actions/checkout@v2 diff --git a/txnkv/transaction/2pc.go b/txnkv/transaction/2pc.go index 2a01befe6..11c1ed0bd 100644 --- a/txnkv/transaction/2pc.go +++ b/txnkv/transaction/2pc.go @@ -1343,12 +1343,15 @@ func keepAlive( } return } - } else { - keepFail = 0 - metrics.TxnHeartBeatHistogramOK.Observe(time.Since(startTime).Seconds()) + continue } - // broadcast to all stores + keepFail = 0 + metrics.TxnHeartBeatHistogramOK.Observe(time.Since(startTime).Seconds()) + // Broadcast to all stores only when the heartbeat succeeds. + // This ensures that PK is the single source of truth for transaction status on the + // TiKV side. It prevents potential inconsistencies where the cached information might + // be more up-to-date than the info stored in the PK. if isPipelinedTxn { broadcastToAllStores( c.txn, @@ -1412,6 +1415,7 @@ func broadcastToAllStores( ResourceGroupName: resourceGroupName, } req.Context.ResourceGroupTag = resourceGroupTag + req.Context.RequestSource = txn.GetRequestSource() _, err := store.GetTiKVClient().SendRequest( bo.GetCtx(),