diff --git a/changes/1.5.0.md b/changes/1.5.0.md index 17e5f5ace8c799736431b81bc760c3239cc58ea3..b9086c5b331e88de783f2c0b492843b63458285e 100644 --- a/changes/1.5.0.md +++ b/changes/1.5.0.md @@ -49,6 +49,7 @@ Seata 鏄竴娆惧紑婧愮殑鍒嗗竷寮忎簨鍔¤В鍐虫柟妗堬紝鎻愪緵楂樻€ц兘鍜岀畝鍗� - [[#3540](https://github.com/seata/seata/pull/3540)] 淇server鍙戝竷鎵撳寘鏃剁己澶辨枃浠� - [[#3573](https://github.com/seata/seata/pull/3573)] 淇 README.md 鏂囦欢涓璁″櫒璺緞閿欒 - [[#3597](https://github.com/seata/seata/pull/3597)] 淇鍙兘瀵艰嚧NPE鐨勯棶棰� + - [[#3133](https://github.com/seata/seata/pull/3133)] 淇鏌愪簺鍦烘櫙涓嬫棤娉曢噸璇曞叏灞€閿佺殑闂 ### optimize锛� diff --git a/changes/en-us/1.5.0.md b/changes/en-us/1.5.0.md index 91c7f2b7226d1fdb13fd0a8d941f2047711ebc33..0428077300cb3fca4f16b3f380ce99c91dad2e81 100644 --- a/changes/en-us/1.5.0.md +++ b/changes/en-us/1.5.0.md @@ -87,6 +87,7 @@ - [[#3551](https://github.com/seata/seata/pull/3551)] make RETRY_DEAD_THRESHOLD bigger and configurable - [[#3589](https://github.com/seata/seata/pull/3589)] Changed exception check by JUnit API usage - [[#3601](https://github.com/seata/seata/pull/3601)] make `LoadBalanceProperties` compatible with `spring-boot:2.x` and above + - [[#3133](https://github.com/seata/seata/pull/3133)] fix the case that could not retry acquire global lock - [[#3631](https://github.com/seata/seata/pull/3631)] optimize nacos-config.py parameter - [[#3638](https://github.com/seata/seata/pull/3638)] optimize the error when use update or delete with join in sql diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java index 5e5c362578c3d0a1117c70f03f5af196f1c6a561..7024f599ee0ba6a5f8a5ad73a55e196c2fdd9ba8 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionProxy.java @@ -50,13 +50,14 @@ public class ConnectionProxy extends AbstractConnectionProxy { private ConnectionContext context = new ConnectionContext(); + private final LockRetryPolicy lockRetryPolicy = new LockRetryPolicy(this); + private static final int REPORT_RETRY_COUNT = ConfigurationFactory.getInstance().getInt( ConfigurationKeys.CLIENT_REPORT_RETRY_COUNT, DEFAULT_CLIENT_REPORT_RETRY_COUNT); public static final boolean IS_REPORT_SUCCESS_ENABLE = ConfigurationFactory.getInstance().getBoolean( ConfigurationKeys.CLIENT_REPORT_SUCCESS_ENABLE, DEFAULT_CLIENT_REPORT_SUCCESS_ENABLE); - private final static LockRetryPolicy LOCK_RETRY_POLICY = new LockRetryPolicy(); /** * Instantiates a new Connection proxy. @@ -181,7 +182,7 @@ public class ConnectionProxy extends AbstractConnectionProxy { @Override public void commit() throws SQLException { try { - LOCK_RETRY_POLICY.execute(() -> { + lockRetryPolicy.execute(() -> { doCommit(); return null; }); @@ -325,10 +326,21 @@ public class ConnectionProxy extends AbstractConnectionProxy { protected static final boolean LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT = ConfigurationFactory .getInstance().getBoolean(ConfigurationKeys.CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT, DEFAULT_CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT); + protected final ConnectionProxy connection; + + public LockRetryPolicy(ConnectionProxy connection) { + this.connection = connection; + } + public <T> T execute(Callable<T> callable) throws Exception { - if (LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT) { + // the only case that not need to retry acquire lock hear is + // LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT == true && connection#autoCommit == true + // because it has retry acquire lock when AbstractDMLBaseExecutor#executeAutoCommitTrue + if (LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT && connection.getContext().isAutoCommitChanged()) { return callable.call(); } else { + // LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT == false + // or LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT == true && autoCommit == false return doRetryOnLockConflict(callable); } } diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java index d42d365bc66191f9bbabd509be0387444acd6d70..ae73f5ddc42c23978682ad9c1ac1e87723eaa693 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/AbstractDMLBaseExecutor.java @@ -172,10 +172,9 @@ public abstract class AbstractDMLBaseExecutor<T, S extends Statement> extends Ba protected abstract TableRecords afterImage(TableRecords beforeImage) throws SQLException; private static class LockRetryPolicy extends ConnectionProxy.LockRetryPolicy { - private final ConnectionProxy connection; LockRetryPolicy(final ConnectionProxy connection) { - this.connection = connection; + super(connection); } @Override diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/ConnectionProxyTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/ConnectionProxyTest.java index 7170f8c6ec1bdbe7ed17beeb7ff5b7b241be8971..016d915dfe349bd0620ee1185a474c8c9c2156fe 100644 --- a/rm-datasource/src/test/java/io/seata/rm/datasource/ConnectionProxyTest.java +++ b/rm-datasource/src/test/java/io/seata/rm/datasource/ConnectionProxyTest.java @@ -22,6 +22,8 @@ import io.seata.core.model.ResourceManager; import io.seata.rm.DefaultResourceManager; import io.seata.rm.datasource.exec.LockConflictException; import io.seata.rm.datasource.exec.LockWaitTimeoutException; +import io.seata.rm.datasource.mock.MockConnection; +import io.seata.rm.datasource.mock.MockDriver; import io.seata.rm.datasource.undo.SQLUndoLog; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -72,11 +74,11 @@ public class ConnectionProxyTest { public void testLockRetryPolicyRollbackOnConflict() throws Exception { boolean oldBranchRollbackFlag = (boolean) branchRollbackFlagField.get(null); branchRollbackFlagField.set(null, true); - ConnectionProxy connectionProxy = new ConnectionProxy(dataSourceProxy, null); + ConnectionProxy connectionProxy = new ConnectionProxy(dataSourceProxy, new MockConnection(new MockDriver(), "", null)); connectionProxy.bind(TEST_XID); connectionProxy.appendUndoLog(new SQLUndoLog()); connectionProxy.appendLockKey(lockKey); - Assertions.assertThrows(LockConflictException.class, connectionProxy::commit); + Assertions.assertThrows(LockWaitTimeoutException.class, connectionProxy::commit); branchRollbackFlagField.set(null, oldBranchRollbackFlag); }