Skip to content

Commit

Permalink
bugfix: modify XA mode pre commit transaction from commit phase to be…
Browse files Browse the repository at this point in the history
…fore close phase (#7102)
  • Loading branch information
xiaoxiangyeyu0 authored Feb 15, 2025
1 parent 6b25b21 commit 56a2f14
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 38 deletions.
1 change: 1 addition & 0 deletions changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#7124](https://github.com/apache/incubator-seata/pull/7124)] bugfix: GlobalTransactionScanner.afterPropertiesSet need do scanner check
- [[#7135](https://github.com/apache/incubator-seata/pull/7135)] treating a unique index conflict during rollback as a dirty write
- [[#7150](https://github.com/apache/incubator-seata/pull/7150)] The time difference between the raft node and the follower node cannot synchronize data
- [[#7102](https://github.com/apache/incubator-seata/pull/7150)] bugfix: modify XA mode pre commit transaction from commit phase to before close phase

### optimize:

Expand Down
1 change: 1 addition & 0 deletions changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- [[#7124](https://github.com/apache/incubator-seata/pull/7124)] GlobalTransactionScanner.afterPropertiesSet方法需要做扫描检查
- [[#7135](https://github.com/apache/incubator-seata/pull/7135)] 回滚时遇到唯一索引冲突视为脏写
- [[#7150](https://github.com/apache/incubator-seata/pull/7150)] raft节点之前时间差,follower节点无法同步数据
- [[#7102](https://github.com/apache/incubator-seata/pull/7150)] 将XA模式预提交事务从提交阶段修改为关闭前阶段

### optimize:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ public void setAutoCommit(boolean autoCommit) throws SQLException {
commit();
}
} else {
if (this.xaBranchXid != null && currentAutoCommitStatus) {
return;
}
if (xaActive) {
throw new SQLException("should NEVER happen: setAutoCommit from true to false while xa branch is active");
}
Expand Down Expand Up @@ -230,36 +233,6 @@ public void commit() throws SQLException {
if (!xaActive || this.xaBranchXid == null) {
throw new SQLException("should NOT commit on an inactive session", SQLSTATE_XA_NOT_END);
}
try {
// XA End: Success
try {
end(XAResource.TMSUCCESS);
} catch (SQLException sqle) {
// Rollback immediately before the XA Branch Context is deleted.
String xaBranchXid = this.xaBranchXid.toString();
rollback();
throw new SQLException("Branch " + xaBranchXid + " was rollbacked on committing since " + sqle.getMessage(), SQLSTATE_XA_NOT_END, sqle);
}
long now = System.currentTimeMillis();
checkTimeout(now);
setPrepareTime(now);
int prepare = xaResource.prepare(xaBranchXid);
// Based on the four databases: MySQL (8), Oracle (12c), Postgres (16), and MSSQL Server (2022),
// only Oracle has read-only optimization; the others do not provide read-only feedback.
// Therefore, the database type check can be eliminated here.
if (prepare == XAResource.XA_RDONLY) {
// Branch Report to TC: RDONLY
reportStatusToTC(BranchStatus.PhaseOne_RDONLY);
}
} catch (XAException xe) {
// Branch Report to TC: Failed
reportStatusToTC(BranchStatus.PhaseOne_Failed);
throw new SQLException(
"Failed to end(TMSUCCESS)/prepare xa branch on " + xid + "-" + xaBranchXid.getBranchId() + " since " + xe
.getMessage(), xe);
} finally {
cleanXABranchContext();
}
}
}

Expand Down Expand Up @@ -336,13 +309,44 @@ private void checkTimeout(Long now) throws XAException {
@Override
public void close() throws SQLException {
try (ResourceLock ignored = resourceLock.obtain()) {
rollBacked = false;
if (isHeld() && shouldBeHeld()) {
// if kept by a keeper, just hold the connection.
return;
try {
if (xaActive && this.xaBranchXid != null) {
// XA End: Success
try {
end(XAResource.TMSUCCESS);
} catch (SQLException sqle) {
// Rollback immediately before the XA Branch Context is deleted.
String xaBranchXid = this.xaBranchXid.toString();
rollback();
throw new SQLException("Branch " + xaBranchXid + " was rollbacked on committing since " + sqle.getMessage(), SQLSTATE_XA_NOT_END, sqle);
}
long now = System.currentTimeMillis();
checkTimeout(now);
setPrepareTime(now);
int prepare = xaResource.prepare(xaBranchXid);
// Based on the four databases: MySQL (8), Oracle (12c), Postgres (16), and MSSQL Server (2022),
// only Oracle has read-only optimization; the others do not provide read-only feedback.
// Therefore, the database type check can be eliminated here.
if (prepare == XAResource.XA_RDONLY) {
// Branch Report to TC: RDONLY
reportStatusToTC(BranchStatus.PhaseOne_RDONLY);
}
}
} catch (XAException xe) {
// Branch Report to TC: Failed
reportStatusToTC(BranchStatus.PhaseOne_Failed);
throw new SQLException(
"Failed to end(TMSUCCESS)/prepare xa branch on " + xid + "-" + xaBranchXid.getBranchId() + " since " + xe
.getMessage(), xe);
} finally {
cleanXABranchContext();
rollBacked = false;
if (isHeld() && shouldBeHeld()) {
// if kept by a keeper, just hold the connection.
} else {
originalConnection.close();
}
}
cleanXABranchContext();
originalConnection.close();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public void testXABranchCommit() throws Throwable {

connectionProxyXA.commit();

Mockito.verify(xaResource).end(any(Xid.class), any(Integer.class));
Mockito.verify(xaResource).prepare(any(Xid.class));
Mockito.verify(xaResource, times(0)).end(any(Xid.class), any(Integer.class));
Mockito.verify(xaResource, times(0)).prepare(any(Xid.class));
}

@Test
Expand Down

0 comments on commit 56a2f14

Please sign in to comment.