From 19a41a0b7b01a7754ddf1587ea76b561195f6b5d Mon Sep 17 00:00:00 2001 From: renliangyu857 <2918490262@qq.com> Date: Tue, 1 Nov 2022 14:10:23 +0800 Subject: [PATCH] optimize: repeat pk in after image sql for INSERT_ON_DUPLICATE_UPDATE (#4995) --- changes/en-us/develop.md | 1 + changes/zh-cn/develop.md | 1 + .../MySQLInsertOnDuplicateUpdateExecutor.java | 19 +++++++++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changes/en-us/develop.md b/changes/en-us/develop.md index ae17be31a24..d93d0fe879f 100644 --- a/changes/en-us/develop.md +++ b/changes/en-us/develop.md @@ -56,6 +56,7 @@ Add changes here for all PR submitted to the develop branch. - [[#4974](https://github.com/seata/seata/pull/4974)] optimize cancel the limit on the number of globalStatus queries in Redis mode - [[#4981](https://github.com/seata/seata/pull/4981)] optimize tcc fence record not exists errMessage - [[#4985](https://github.com/seata/seata/pull/4985)] fix undo_log id repeat +- [[#4995](https://github.com/seata/seata/pull/4995)] fix mysql InsertOnDuplicateUpdate duplicate pk condition in after image query sql ### test: diff --git a/changes/zh-cn/develop.md b/changes/zh-cn/develop.md index 18687d9cf1f..96866bb9349 100644 --- a/changes/zh-cn/develop.md +++ b/changes/zh-cn/develop.md @@ -57,6 +57,7 @@ - [[#4962](https://github.com/seata/seata/pull/4962)] 优化构建配置,并修正docker镜像的基础镜像 - [[#4974](https://github.com/seata/seata/pull/4974)] 取消redis模式下,查询globalStatus条数的限制 - [[#4981](https://github.com/seata/seata/pull/4981)] 优化当tcc栅栏记录查不到时的错误提示 +- [[#4995](https://github.com/seata/seata/pull/4995)] 修复mysql InsertOnDuplicateUpdate后置镜像查询SQL中重复的主键查询条件 ### test: - [[#4794](https://github.com/seata/seata/pull/4794)] 重构代码,尝试修复单元测试 `DataSourceProxyTest.getResourceIdTest()` diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLInsertOnDuplicateUpdateExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLInsertOnDuplicateUpdateExecutor.java index b1fd711c2ed..31f23161790 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLInsertOnDuplicateUpdateExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/mysql/MySQLInsertOnDuplicateUpdateExecutor.java @@ -19,10 +19,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.Collections; +import java.util.Set; import java.util.StringJoiner; import java.util.stream.Collectors; @@ -84,6 +86,11 @@ public ArrayList> getParamAppenderList() { */ private ArrayList> paramAppenderList; + /** + * the primary keys in before image sql. if the primary key is auto increment,the set is empty + */ + private Set primaryKeysInBeforeImageSql = new HashSet<>(4); + public MySQLInsertOnDuplicateUpdateExecutor(StatementProxy statementProxy, StatementCallback statementCallback, SQLRecognizer sqlRecognizer) { super(statementProxy, statementCallback, sqlRecognizer); } @@ -224,8 +231,10 @@ protected TableRecords afterImage(TableRecords beforeImage) throws SQLException for (int i = 0; i < rows.size(); i++) { List wherePrimaryList = new ArrayList<>(); primaryValueMap.forEach((k, v) -> { - wherePrimaryList.add(k + " = ? "); - primaryValues.add(v); + if (!primaryKeysInBeforeImageSql.contains(k)) { + wherePrimaryList.add(k + " = ? "); + primaryValues.add(v); + } }); afterImageSql.append(" OR (").append(Joiner.on(" and ").join(wherePrimaryList)).append(") "); } @@ -305,6 +314,9 @@ public String buildImageSQL(TableMeta tableMeta) { List imageParameters = imageParameterMap.get(columnName); if (imageParameters == null && m.getColumnDef() != null) { uniqueList.add(columnName + " = DEFAULT(" + columnName + ") "); + if ("PRIMARY".equalsIgnoreCase(k)) { + primaryKeysInBeforeImageSql.add(columnName); + } columnIsNull = false; continue; } @@ -317,6 +329,9 @@ public String buildImageSQL(TableMeta tableMeta) { } break; } + if ("PRIMARY".equalsIgnoreCase(k)) { + primaryKeysInBeforeImageSql.add(columnName); + } columnIsNull = false; uniqueList.add(columnName + " = ? "); paramAppenderTempList.add(imageParameters.get(finalI));