diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/BaseDatabaseOperate.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/BaseDatabaseOperate.java index 72469e39f..f3625f359 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/BaseDatabaseOperate.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/BaseDatabaseOperate.java @@ -32,6 +32,7 @@ import org.springframework.transaction.support.TransactionTemplate; import java.util.List; import java.util.Map; +import java.util.function.BiConsumer; import java.util.stream.IntStream; import static com.alibaba.nacos.config.server.utils.LogUtil.FATAL_LOG; @@ -196,6 +197,19 @@ public interface BaseDatabaseOperate extends DatabaseOperate { */ default Boolean update(TransactionTemplate transactionTemplate, JdbcTemplate jdbcTemplate, List contexts) { + return update(transactionTemplate, jdbcTemplate, contexts, null); + } + + /** + * execute update operation, to fix #3617. + * + * @param transactionTemplate {@link TransactionTemplate} + * @param jdbcTemplate {@link JdbcTemplate} + * @param contexts {@link List} ModifyRequest list + * @return {@link Boolean} + */ + default Boolean update(TransactionTemplate transactionTemplate, JdbcTemplate jdbcTemplate, + List contexts, BiConsumer consumer) { return transactionTemplate.execute(status -> { String[] errSql = new String[] {null}; Object[][] args = new Object[][] {null}; @@ -207,10 +221,16 @@ public interface BaseDatabaseOperate extends DatabaseOperate { LoggerUtils.printIfDebugEnabled(LogUtil.DEFAULT_LOG, "current args : {}", args[0]); jdbcTemplate.update(pair.getSql(), pair.getArgs()); }); + if (consumer != null) { + consumer.accept(Boolean.TRUE, null); + } return Boolean.TRUE; } catch (BadSqlGrammarException | DataIntegrityViolationException e) { FATAL_LOG.error("[db-error] sql : {}, args : {}, error : {}", errSql[0], args[0], e.toString()); - return false; + if (consumer != null) { + consumer.accept(Boolean.FALSE, e); + } + return Boolean.FALSE; } catch (CannotGetJdbcConnectionException e) { FATAL_LOG.error("[db-error] sql : {}, args : {}, error : {}", errSql[0], args[0], e.toString()); throw e; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DatabaseOperate.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DatabaseOperate.java index 49342704f..7f75deb2a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DatabaseOperate.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/DatabaseOperate.java @@ -133,8 +133,20 @@ public interface DatabaseOperate { * @return is success */ default Boolean blockUpdate() { + return blockUpdate(null); + } + + /** + * data modify transaction The SqlContext to be executed in the current thread will be executed and automatically + * cleared. + * @author klw(213539@qq.com) + * 2020/8/24 18:16 + * @param consumer the consumer + * @return java.lang.Boolean + */ + default Boolean blockUpdate(BiConsumer consumer) { try { - return update(EmbeddedStorageContextUtils.getCurrentSqlContext(), null); + return update(EmbeddedStorageContextUtils.getCurrentSqlContext(), consumer); } finally { EmbeddedStorageContextUtils.cleanAllContext(); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java index 461a48812..04d9fd71f 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedStoragePersistServiceImpl.java @@ -17,6 +17,7 @@ package com.alibaba.nacos.config.server.service.repository.embedded; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.runtime.NacosRuntimeException; import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.config.server.configuration.ConditionOnEmbeddedStorage; @@ -70,6 +71,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; +import java.util.function.BiConsumer; import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.CONFIG_ADVANCE_INFO_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.RowMapperManager.CONFIG_ALL_INFO_ROW_MAPPER; @@ -189,6 +191,12 @@ public class EmbeddedStoragePersistServiceImpl implements PersistService { @Override public void addConfigInfo(final String srcIp, final String srcUser, final ConfigInfo configInfo, final Timestamp time, final Map configAdvanceInfo, final boolean notify) { + addConfigInfo(srcIp, srcUser, configInfo, time, configAdvanceInfo, notify, null); + } + + private void addConfigInfo(final String srcIp, final String srcUser, final ConfigInfo configInfo, + final Timestamp time, final Map configAdvanceInfo, final boolean notify, + BiConsumer consumer) { try { final String tenantTmp = @@ -205,7 +213,7 @@ public class EmbeddedStoragePersistServiceImpl implements PersistService { configInfo.getTenant()); insertConfigHistoryAtomic(hisId, configInfo, srcIp, srcUser, time, "I"); EmbeddedStorageContextUtils.onModifyConfigInfo(configInfo, srcIp, time); - databaseOperate.blockUpdate(); + databaseOperate.blockUpdate(consumer); } finally { EmbeddedStorageContextUtils.cleanAllContext(); } @@ -2291,6 +2299,12 @@ public class EmbeddedStoragePersistServiceImpl implements PersistService { int skipCount = 0; List> failData = null; List> skipData = null; + + final BiConsumer callFinally = (result, t) -> { + if (t != null) { + throw new NacosRuntimeException(0, t); + } + }; for (int i = 0; i < configInfoList.size(); i++) { ConfigAllInfo configInfo = configInfoList.get(i); @@ -2322,10 +2336,10 @@ public class EmbeddedStoragePersistServiceImpl implements PersistService { } configAdvanceInfo.put("type", type); try { - addConfigInfo(srcIp, srcUser, configInfo2Save, time, configAdvanceInfo, notify); + addConfigInfo(srcIp, srcUser, configInfo2Save, time, configAdvanceInfo, notify, callFinally); succCount++; } catch (Throwable e) { - if (!StringUtils.contains("DuplicateKeyException", e.toString())) { + if (!StringUtils.contains(e.toString(), "DuplicateKeyException")) { throw e; } // uniqueness constraint conflict diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/StandaloneDatabaseOperateImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/StandaloneDatabaseOperateImpl.java index d02ac7ce1..332494fb0 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/StandaloneDatabaseOperateImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/StandaloneDatabaseOperateImpl.java @@ -128,7 +128,7 @@ public class StandaloneDatabaseOperateImpl implements BaseDatabaseOperate { @Override public Boolean update(List modifyRequests, BiConsumer consumer) { - return update(modifyRequests); + return update(transactionTemplate, jdbcTemplate, modifyRequests, consumer); } @Override