diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d257cae269b0d179e6576777d82382abbbce2e6d..1e8139d651d0bb7823324c7a59fe0a58ba7cfb36 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,6 @@ jobs: runs-on: ${{ matrix.os }} strategy: - max-parallel: 1 matrix: java: [8, 11] os: [ ubuntu-18.04 ] diff --git a/changes/1.5.0.md b/changes/1.5.0.md index 2cd44f4fcb93a09453b7e6c17de492ba5aa481fc..45a2301aab1ad0579503c1c94f565e01787677ee 100644 --- a/changes/1.5.0.md +++ b/changes/1.5.0.md @@ -18,12 +18,15 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 ### feature: - [[#3172](https://github.com/seata/seata/pull/3172)] 支持undolog压缩 + - [[#3372](https://github.com/seata/seata/pull/3372)] saga模式下支撑用户自定义是否更新最后一次重试日志 ### bugfix: - [[#3258](https://github.com/seata/seata/pull/3258)] 修复AsyncWorker潜在的OOM问题 - [[#3293](https://github.com/seata/seata/pull/3293)] 修复配置缓存获取值时类型不匹配的bug + - [[#3241](https://github.com/seata/seata/pull/3241)] 禁止在多SQL的情况下使用 limit 和 order by 语法 + ### optimize: @@ -39,6 +42,13 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [[#3365](https://github.com/seata/seata/pull/3365)] 修复ParameterParserTest测试用例 - [[#3359](https://github.com/seata/seata/pull/3359)] 删除未使用的测试用例 - [[#3397](https://github.com/seata/seata/pull/3397)] 添加更改记录文件夹 + + + + ### test + + - [[#3381](https://github.com/seata/seata/pull/3381)] 添加 TmClient 的测试用例 + 非常感谢以下 contributors 的代码贡献。若有无意遗漏,请报告。 @@ -49,6 +59,8 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单 - [jsbxyyx](https://github.com/jsbxyyx) - [caohdgege](https://github.com/caohdgege) - [a364176773](https://github.com/a364176773) + - [anselleeyy](https://github.com/anselleeyy) + - [Ifdevil](https://github.com/Ifdevil) 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。 diff --git a/changes/en-us/1.5.0.md b/changes/en-us/1.5.0.md index 9f2d557e7ebda9b634a6ecd066add6750b207672..2c4e1a559358cf8b630b100026da37c7fbf3ea09 100644 --- a/changes/en-us/1.5.0.md +++ b/changes/en-us/1.5.0.md @@ -18,12 +18,14 @@ ### feature: - [[#3172](https://github.com/seata/seata/pull/3172)] support rollback info compress + - [[#3372](https://github.com/seata/seata/pull/3372)] Saga support customize whether update last retry log ### bugfix: - [[#3258](https://github.com/seata/seata/pull/3258)] fix AsyncWorker potential OOM problem - [[#3293](https://github.com/seata/seata/pull/3293)] configuration cache get value cast exception + - [[#3241](https://github.com/seata/seata/pull/3241)] forbidden use order by or limit in multi sql ### optimize: @@ -39,6 +41,10 @@ - [[#3365](https://github.com/seata/seata/pull/3365)] optimize ParameterParserTest test case failed - [[#3359](https://github.com/seata/seata/pull/3359)] remove unused test case - [[#3397](https://github.com/seata/seata/pull/3397)] add the change records folder + + ### test + + - [[#3381](https://github.com/seata/seata/pull/3381)] test case for tmClient Thanks to these contributors for their code commits. Please report an unintended omission. @@ -48,7 +54,9 @@ - [hoverruan](https://github.com/hoverruan ) - [jsbxyyx](https://github.com/jsbxyyx) - [caohdgege](https://github.com/caohdgege) - - [a364176773](https://github.com/a364176773) + - [a364176773](https://github.com/a364176773) + - [anselleeyy](https://github.com/anselleeyy) + - [Ifdevil](https://github.com/Ifdevil) Also, we receive many valuable issues, questions and advices from our community. Thanks for you all. diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiDeleteExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiDeleteExecutor.java index 1c8d34e63bc903d0bcfa34ea9364d6a9d408127f..5eb2418b033547d0ca1f7b747718ec94cede17fd 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiDeleteExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiDeleteExecutor.java @@ -15,6 +15,7 @@ */ package io.seata.rm.datasource.exec; +import io.seata.common.exception.NotSupportYetException; import io.seata.common.util.StringUtils; @@ -22,6 +23,7 @@ import io.seata.rm.datasource.ColumnUtils; import io.seata.rm.datasource.StatementProxy; import io.seata.rm.datasource.sql.struct.TableMeta; import io.seata.rm.datasource.sql.struct.TableRecords; +import io.seata.sqlparser.ParametersHolder; import io.seata.sqlparser.SQLDeleteRecognizer; import io.seata.sqlparser.SQLRecognizer; @@ -55,6 +57,15 @@ public class MultiDeleteExecutor<T, S extends Statement> extends AbstractDMLBase for (SQLRecognizer recognizer : sqlRecognizers) { sqlRecognizer = recognizer; SQLDeleteRecognizer visitor = (SQLDeleteRecognizer) recognizer; + + ParametersHolder parametersHolder = statementProxy instanceof ParametersHolder ? (ParametersHolder)statementProxy : null; + if (StringUtils.isNotBlank(visitor.getLimit(parametersHolder, paramAppenderList))) { + throw new NotSupportYetException("Multi delete SQL with limit condition is not support yet !"); + } + if (StringUtils.isNotBlank(visitor.getOrderBy())) { + throw new NotSupportYetException("Multi delete SQL with orderBy condition is not support yet !"); + } + String whereConditionStr = buildWhereCondition(visitor, paramAppenderList); if (StringUtils.isBlank(whereConditionStr)) { whereCondition = new StringBuilder(); diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiUpdateExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiUpdateExecutor.java index 13101f3a3299dc3c4cca1434a3c844b9466f2ee4..ff69ebae7ab1150d2312a9e192851a726982d801 100644 --- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiUpdateExecutor.java +++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/MultiUpdateExecutor.java @@ -25,6 +25,7 @@ import java.util.Set; import java.util.HashSet; import java.util.StringJoiner; +import io.seata.common.exception.NotSupportYetException; import io.seata.common.util.IOUtil; import io.seata.common.util.StringUtils; import io.seata.config.Configuration; @@ -36,6 +37,7 @@ import io.seata.rm.datasource.SqlGenerateUtils; import io.seata.rm.datasource.StatementProxy; import io.seata.rm.datasource.sql.struct.TableMeta; import io.seata.rm.datasource.sql.struct.TableRecords; +import io.seata.sqlparser.ParametersHolder; import io.seata.sqlparser.SQLRecognizer; import io.seata.sqlparser.SQLUpdateRecognizer; @@ -79,6 +81,15 @@ public class MultiUpdateExecutor<T, S extends Statement> extends AbstractDMLBase for (SQLRecognizer recognizer : sqlRecognizers) { sqlRecognizer = recognizer; SQLUpdateRecognizer sqlUpdateRecognizer = (SQLUpdateRecognizer) recognizer; + + ParametersHolder parametersHolder = statementProxy instanceof ParametersHolder ? (ParametersHolder)statementProxy : null; + if (StringUtils.isNotBlank(sqlUpdateRecognizer.getLimit(parametersHolder, paramAppenderList))) { + throw new NotSupportYetException("Multi update SQL with limit condition is not support yet !"); + } + if (StringUtils.isNotBlank(sqlUpdateRecognizer.getOrderBy())) { + throw new NotSupportYetException("Multi update SQL with orderBy condition is not support yet !"); + } + List<String> updateColumns = sqlUpdateRecognizer.getUpdateColumns(); updateColumnsSet.addAll(updateColumns); if (noWhereCondition) { diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/exec/MultiExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/exec/MultiExecutorTest.java index 9d89a3e96648d5bdc724611e5c511bef48e5e87d..4da7b39d8236a32d6d6d261b4dd3079eff96a4e5 100644 --- a/rm-datasource/src/test/java/io/seata/rm/datasource/exec/MultiExecutorTest.java +++ b/rm-datasource/src/test/java/io/seata/rm/datasource/exec/MultiExecutorTest.java @@ -22,6 +22,7 @@ import com.alibaba.druid.sql.SQLUtils; import com.alibaba.druid.sql.ast.SQLStatement; import com.alibaba.druid.util.JdbcConstants; import com.google.common.collect.Lists; +import io.seata.common.exception.NotSupportYetException; import io.seata.rm.datasource.ConnectionProxy; import io.seata.rm.datasource.DataSourceProxy; import io.seata.rm.datasource.StatementProxy; @@ -174,9 +175,38 @@ public class MultiExecutorTest { Assertions.assertTrue(itemSet.contains("table_update_executor_test2")); Assertions.assertEquals(items.size(), 2); + // contains limit delete + sql = "delete from table_update_executor_test2 where id = 2;delete from table_update_executor_test2 where id = 2 limit 1;"; + multi = SQLVisitorFactory.get(sql, JdbcConstants.MYSQL); + executor = new MultiExecutor(statementProxy, (statement, args) -> { + return null; + }, multi); + Assertions.assertThrows(NotSupportYetException.class, executor::beforeImage); + // contains order by and limit delete + sql = "delete from table_update_executor_test2 where id = 2;delete from table_update_executor_test2 where id = 2 order by id desc limit 1;"; + multi = SQLVisitorFactory.get(sql, JdbcConstants.MYSQL); + executor = new MultiExecutor(statementProxy, (statement, args) -> { + return null; + }, multi); + Assertions.assertThrows(NotSupportYetException.class, executor::beforeImage); + //contains order by update + sql = "update table_update_executor_test set name = 'WILL' where id = 1;update table_update_executor_test set name = 'WILL' where id = 1 order by id desc;"; + multi = SQLVisitorFactory.get(sql, JdbcConstants.MYSQL); + executor = new MultiExecutor(statementProxy, (statement, args) -> { + return null; + }, multi); + Assertions.assertThrows(NotSupportYetException.class, executor::beforeImage); + + //contains order by and limit update + sql = "update table_update_executor_test set name = 'WILL' where id = 1;update table_update_executor_test set name = 'WILL' where id = 1 order by id desc limit 1;"; + multi = SQLVisitorFactory.get(sql, JdbcConstants.MYSQL); + executor = new MultiExecutor(statementProxy, (statement, args) -> { + return null; + }, multi); + Assertions.assertThrows(NotSupportYetException.class, executor::beforeImage); } }