Skip to content
2 changes: 1 addition & 1 deletion changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#7356](https://github.com/apache/incubator-seata/pull/7356)] fix codecov bug
- [[#7370](https://github.com/apache/incubator-seata/pull/7370)] fix ISSUE_TEMPLATE not work
- [[#7397](https://github.com/apache/incubator-seata/pull/7397)] Resolve NullPointer and port binding errors

- [[#7480](https://github.com/apache/incubator-seata/pull/7480)] Failure to Enter TimeoutRollbackRetrying State

### optimize:

Expand Down
2 changes: 1 addition & 1 deletion changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
- [[#7356](https://github.com/apache/incubator-seata/pull/7356)] 修复 codecov 错误
- [[#7370](https://github.com/apache/incubator-seata/pull/7370)] 修复 ISSUE_TEMPLATE 不可用
- [[#7397](https://github.com/apache/incubator-seata/pull/7397)] 解决空指针和端口绑定错误

- [[#7480](https://github.com/apache/incubator-seata/pull/7480)] 解决无法扭转到TimeoutRollbackRetrying状态

### optimize:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) t
"Rollback branch transaction fail and will retry, xid = {} branchId = {}",
globalSession.getXid(),
branchSession.getBranchId());
if (!retrying) {
if (shouldQueueToRetryRollback(retrying, globalSession)) {
globalSession.queueToRetryRollback();
}
return false;
Expand All @@ -486,7 +486,7 @@ public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) t
String.valueOf(retrying),
ex.getMessage()
});
if (!retrying) {
if (shouldQueueToRetryRollback(retrying, globalSession)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Does it mean moving the logic of shouldQueueToRetryRollback(retrying, globalSession) into globalSession.queueToRetryRollback()?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Does it mean moving the logic of shouldQueueToRetryRollback(retrying, globalSession) into globalSession.queueToRetryRollback()?

Yes, because regardless of whether it is in a retry state or not, the transaction always transitions from state A to a substate of A, such as Committing. If the transaction in this state fails, the state will change to CommitRetry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Does it mean moving the logic of shouldQueueToRetryRollback(retrying, globalSession) into globalSession.queueToRetryRollback()?

Yes, because regardless of whether it is in a retry state or not, the transaction always transitions from state A to a substate of A, such as Committing. If the transaction in this state fails, the state will change to CommitRetry.

Ok,is it like this?

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@funky-eyes 这里辛苦再帮忙看看

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Does it mean moving the logic of shouldQueueToRetryRollback(retrying, globalSession) into globalSession.queueToRetryRollback()?

Yes, because regardless of whether it is in a retry state or not, the transaction always transitions from state A to a substate of A, such as Committing. If the transaction in this state fails, the state will change to CommitRetry.

Ok,is it like this?

image

yes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not directly remove this retrying check? Then handle the transaction state transition in the queueToRetryRollback method instead?

Does it mean moving the logic of shouldQueueToRetryRollback(retrying, globalSession) into globalSession.queueToRetryRollback()?

Yes, because regardless of whether it is in a retry state or not, the transaction always transitions from state A to a substate of A, such as Committing. If the transaction in this state fails, the state will change to CommitRetry.

Ok,is it like this?
image

yes

done

globalSession.queueToRetryRollback();
}
throw new TransactionException(ex);
Expand Down Expand Up @@ -547,4 +547,8 @@ private boolean isXaerNotaTimeout(GlobalSession globalSession, BranchStatus bran
return false;
}
}

private boolean shouldQueueToRetryRollback(boolean retrying, GlobalSession globalSession) {
return !retrying || globalSession.getStatus().equals(GlobalStatus.TimeoutRollbacking);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,26 @@ public void doGlobalRollBackRetryableExpTest(String xid) throws Exception {
Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.RollbackRetrying);
}

/**
* Do TimeoutRollbacking test.
*
* @param xid the xid
* @throws Exception the exception
*/
@ParameterizedTest
@MethodSource("xidProvider")
public void doGlobalRollbackTimeoutRollbackingRetryingTest(String xid) throws Exception {
globalSession = SessionHolder.findGlobalSession(xid);
BranchSession branchSession = SessionHelper.newBranchByGlobal(
globalSession, BranchType.AT, resourceId, applicationData, "t1:1", clientId);
globalSession.addBranch(branchSession);
globalSession.changeBranchStatus(branchSession, BranchStatus.Registered);
globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbacking);
core.mockCore(BranchType.AT, new MockCore(BranchStatus.PhaseTwo_Committed, BranchStatus.Registered));
core.doGlobalRollback(globalSession, true);
Assertions.assertEquals(GlobalStatus.TimeoutRollbackRetrying, globalSession.getStatus());
}

/**
* Xid provider object [ ] [ ].
*
Expand Down
Loading