[Fix][Connector-Jdbc]prevent duplicate XA XID in exactly-once writer and rollback prepared tx on begin failure#10459
[Fix][Connector-Jdbc]prevent duplicate XA XID in exactly-once writer and rollback prepared tx on begin failure#10459yzeng1618 wants to merge 3 commits intoapache:devfrom
Conversation
…and rollback prepared tx on begin failure
Issue 1: Test constructor visibility issueLocation: JdbcExactlyOnceSinkWriter(
SinkWriter.Context sinkcontext,
JobContext context,
List<JdbcSinkState> states,
XaFacade xaFacade,
XaGroupOps xaGroupOps,
XidGenerator xidGenerator,
JdbcOutputFormat<SeaTunnelRow, JdbcBatchStatementExecutor<SeaTunnelRow>> outputFormat) {
// ... initialization code
}Issue Description:
Potential Risks:
Impact Scope:
Severity: MINOR Suggestion: JdbcExactlyOnceSinkWriter(
SinkWriter.Context sinkcontext,
JobContext context,
List<JdbcSinkState> states,
XaFacade xaFacade,
XaGroupOps xaGroupOps,
XidGenerator xidGenerator,
JdbcOutputFormat<SeaTunnelRow, JdbcBatchStatementExecutor<SeaTunnelRow>> outputFormat) {
this.sinkcontext = sinkcontext;
this.context = context;
this.recoverStates = states;
this.connectionProvider = xaFacade;
this.xaFacade = xaFacade;
this.xaGroupOps = xaGroupOps;
this.xidGenerator = xidGenerator;
this.outputFormat = outputFormat;
// Add this line to ensure initialization
this.xidGenerator.open();
}Rationale: Ensure consistent behavior between the test constructor and production constructor. Issue 2: Initialization value of lastGeneratedTxId may cause early ID range wasteLocation: private transient long lastGeneratedTxId = Long.MIN_VALUE;Issue Description:
Potential Risks:
Impact Scope:
Severity: MINOR Suggestion: private transient long lastGeneratedTxId = -1; // Use -1 to indicate uninitializedRationale: Issue 3: MultiTableSinkCommitter's commit method has the same issueLocation: Issue Description:
Potential Risks:
Impact Scope:
Severity: MINOR Suggestion: Issue 4: Missing integration tests for empty transaction scenariosLocation: Issue Description:
Potential Risks:
Impact Scope:
Severity: MINOR Suggestion: @Test
void testPrepareCommitWithEmptyTransactionDontRollback() throws Exception {
TestContext context = createWriter();
// Simulate prepare returning empty transaction
when(context.xaFacade.endAndPrepare(any()))
.thenThrow(new XaFacade.EmptyXaTransactionException(mock(Xid.class)));
// Simulate beginTx failure
doThrow(new RuntimeException("start tx failed"))
.when(context.xaFacade)
.start(any());
Assertions.assertThrows(
JdbcConnectorException.class, () -> context.writer.prepareCommit(10L));
// Verify rollback is not called (because it's an empty transaction)
verify(context.xaFacade, never()).rollback(any());
} |
|
The relevant content has been optimized in accordance with the suggestions. |
Purpose of this pull request
Fixes #10449
This PR fixes XA transaction stability issues in JDBC exactly-once writer and a related multi-table abort routing issue.
Does this PR introduce any user-facing change?
Yes.
Previous behavior:
beginTxfailed after a successful prepare, prepared XA transactions could remain and hold locks.New behavior:
How was this patch tested?
Added tests:
JdbcExactlyOnceSinkWriterTesttestPrepareCommitWithSameCheckpointGeneratesMonotonicTxIdstestPrepareCommitRollbackPreparedXidWhenStartNextTxFailedtestAbortPrepareRollbackPreparedAndCurrentTransactiontestCloseRollbackPreparedAndCurrentTransactionMultiTableSinkCommitterTesttestRouteByTableIdentifierForCommitAndAbortCheck list
New License Guide
incompatible-changes.mdto describe the incompatibility caused by this PR.