From 363e1792ba52e1dfeea049842ca5b71d373d49fe Mon Sep 17 00:00:00 2001 From: GoodBoyCoder Date: Mon, 4 Nov 2024 09:33:59 +0800 Subject: [PATCH 1/8] feature: add fastjson2 undolog parser (#6974) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 1 + rm-datasource/pom.xml | 6 ++ .../undo/parser/Fastjson2UndoLogParser.java | 77 +++++++++++++++++++ ...che.seata.rm.datasource.undo.UndoLogParser | 3 +- .../parser/Fastjson2UndoLogParserTest.java | 36 +++++++++ 6 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParser.java create mode 100644 rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParserTest.java diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 969b9578bea..f0c1b9198a7 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -7,6 +7,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6876](https://github.com/apache/incubator-seata/pull/6876)] support kingbase - [[#6881](https://github.com/apache/incubator-seata/pull/6881)] support grpc - [[#6864](https://github.com/apache/incubator-seata/pull/6864)] support shentong database +- [[#6974](https://github.com/apache/incubator-seata/pull/6974)] support fastjson2 undolog parser ### bugfix: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 873f126b64a..ae9c1047dd9 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -7,6 +7,7 @@ - [[#6876](https://github.com/apache/incubator-seata/pull/6876)] 支持人大金仓数据库(kingbase) - [[#6881](https://github.com/apache/incubator-seata/pull/6881)] client和server支持grpc协议 - [[#6864](https://github.com/apache/incubator-seata/pull/6864)] 支持神通数据库(oscar) +- [[#6974](https://github.com/apache/incubator-seata/pull/6974)] 支持UndoLog的fastjson2序列化方式 ### bugfix: diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml index ed466e2cdf1..af2c0d09f59 100644 --- a/rm-datasource/pom.xml +++ b/rm-datasource/pom.xml @@ -111,6 +111,12 @@ provided true + + com.alibaba.fastjson2 + fastjson2 + provided + true + com.alibaba druid diff --git a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParser.java b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParser.java new file mode 100644 index 00000000000..d26a041f704 --- /dev/null +++ b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParser.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.rm.datasource.undo.parser; + +import com.alibaba.fastjson2.JSONB; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import org.apache.seata.common.executor.Initialize; +import org.apache.seata.common.loader.LoadLevel; +import org.apache.seata.rm.datasource.undo.BranchUndoLog; +import org.apache.seata.rm.datasource.undo.UndoLogParser; + +@LoadLevel(name = Fastjson2UndoLogParser.NAME) +public class Fastjson2UndoLogParser implements UndoLogParser, Initialize { + public static final String NAME = "fastjson2"; + + private JSONReader.Feature[] jsonReaderFeature; + private JSONWriter.Feature[] jsonWriterFeature; + @Override + public void init() { + jsonReaderFeature = new JSONReader.Feature[]{ + JSONReader.Feature.UseDefaultConstructorAsPossible, + // If not configured, it will be serialized based on public field and getter methods by default. + // After configuration, it will be deserialized based on non-static fields (including private). + // It will be safer under FieldBased configuration + JSONReader.Feature.FieldBased, + JSONReader.Feature.IgnoreAutoTypeNotMatch, + JSONReader.Feature.UseNativeObject, + JSONReader.Feature.SupportAutoType + }; + + jsonWriterFeature = new JSONWriter.Feature[]{ + JSONWriter.Feature.WriteClassName, + JSONWriter.Feature.FieldBased, + JSONWriter.Feature.ReferenceDetection, + JSONWriter.Feature.WriteNulls, + JSONWriter.Feature.NotWriteDefaultValue, + JSONWriter.Feature.NotWriteHashMapArrayListClassName, + JSONWriter.Feature.WriteNameAsSymbol + }; + } + + @Override + public String getName() { + return NAME; + } + + @Override + public byte[] getDefaultContent() { + return encode(new BranchUndoLog()); + } + + @Override + public byte[] encode(BranchUndoLog branchUndoLog) { + return JSONB.toBytes(branchUndoLog, jsonWriterFeature); + } + + @Override + public BranchUndoLog decode(byte[] bytes) { + return JSONB.parseObject(bytes, BranchUndoLog.class, jsonReaderFeature); + } + +} diff --git a/rm-datasource/src/main/resources/META-INF/services/org.apache.seata.rm.datasource.undo.UndoLogParser b/rm-datasource/src/main/resources/META-INF/services/org.apache.seata.rm.datasource.undo.UndoLogParser index 26abca209ed..9a32cda00b5 100644 --- a/rm-datasource/src/main/resources/META-INF/services/org.apache.seata.rm.datasource.undo.UndoLogParser +++ b/rm-datasource/src/main/resources/META-INF/services/org.apache.seata.rm.datasource.undo.UndoLogParser @@ -17,4 +17,5 @@ org.apache.seata.rm.datasource.undo.parser.FastjsonUndoLogParser org.apache.seata.rm.datasource.undo.parser.JacksonUndoLogParser org.apache.seata.rm.datasource.undo.parser.ProtostuffUndoLogParser -org.apache.seata.rm.datasource.undo.parser.KryoUndoLogParser \ No newline at end of file +org.apache.seata.rm.datasource.undo.parser.KryoUndoLogParser +org.apache.seata.rm.datasource.undo.parser.Fastjson2UndoLogParser \ No newline at end of file diff --git a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParserTest.java b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParserTest.java new file mode 100644 index 00000000000..21059c8a812 --- /dev/null +++ b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/undo/parser/Fastjson2UndoLogParserTest.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.rm.datasource.undo.parser; + +import org.apache.seata.common.loader.EnhancedServiceLoader; +import org.apache.seata.rm.datasource.undo.BaseUndoLogParserTest; +import org.apache.seata.rm.datasource.undo.UndoLogParser; + + +public class Fastjson2UndoLogParserTest extends BaseUndoLogParserTest { + + Fastjson2UndoLogParser parser = (Fastjson2UndoLogParser) EnhancedServiceLoader.load(UndoLogParser.class, Fastjson2UndoLogParser.NAME); + + @Override + public UndoLogParser getParser() { + return parser; + } + + @Override + public void testTimestampEncodeAndDecode() { + } +} From 78a070836188edf09dfb8b5f89e356beb172d478 Mon Sep 17 00:00:00 2001 From: psxjoy Date: Wed, 6 Nov 2024 11:26:31 +0800 Subject: [PATCH 2/8] bugfix: support building docker image on openjdk23 (#6984) --- build/pom.xml | 2 +- changes/en-us/2.x.md | 2 ++ changes/zh-cn/2.x.md | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/pom.xml b/build/pom.xml index 9e26a12f1a1..d54230f995d 100644 --- a/build/pom.xml +++ b/build/pom.xml @@ -120,7 +120,7 @@ 2.4.3 3.0.2 3.0.0 - 3.2.0 + 3.3.0 4.9.10 1.15.0 diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index f0c1b9198a7..5e7938a1981 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -21,6 +21,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6943](https://github.com/apache/incubator-seata/pull/6943)] fix the conversion error for `convertBranchSession` in concurrent environment. - [[#6948](https://github.com/apache/incubator-seata/pull/6948)] Fix the CI build issue on the ARM64 platform - [[#6947](https://github.com/apache/incubator-seata/pull/6947)] fix npe for nacos registry when look up address +- [[#6984](https://github.com/apache/incubator-seata/pull/6984)] support building docker image on openjdk23 ### optimize: - [[#6826](https://github.com/apache/incubator-seata/pull/6826)] remove the branch registration operation of the XA read-only transaction @@ -41,6 +42,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] Remove JVM parameter app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] update the naming and description for the `seata-http-jakarta` module + ### refactor: ### security: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index ae9c1047dd9..87e3c059ab4 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -21,6 +21,7 @@ - [[#6943](https://github.com/apache/incubator-seata/pull/6943)] 修复并发状态下 `convertBranchSession` 转换报错问题 - [[#6948](https://github.com/apache/incubator-seata/pull/6948)] 修复在ARM64平台下CI构建出错的问题 - [[#6947](https://github.com/apache/incubator-seata/pull/6947)] 修复nacos注册中心查询可用地址时的空指针问题 +- [[#6984](https://github.com/apache/incubator-seata/pull/6984)] 修复 openjdk23 版本下无法构建 docker 镜像的问题 ### optimize: - [[#6826](https://github.com/apache/incubator-seata/pull/6826)] 移除只读XA事务的分支注册操作 From 835ef47448c1c0819552297bd3c45d61125edcd5 Mon Sep 17 00:00:00 2001 From: funkye Date: Sun, 10 Nov 2024 12:29:30 +0800 Subject: [PATCH 3/8] optimize: gRPC serialization default to Protobuf (#6991) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 1 + .../java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 5e7938a1981..8ba55503320 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -41,6 +41,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6938](https://github.com/apache/incubator-seata/pull/6938)] Update online chat information in README.md - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] Remove JVM parameter app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] update the naming and description for the `seata-http-jakarta` module +- [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC serialization default to Protobuf ### refactor: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 87e3c059ab4..915a039cbb9 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -43,6 +43,7 @@ - [[#6938](https://github.com/apache/incubator-seata/pull/6938)] 更新 README.md 中的社区联系信息 - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] 移除JVM参数app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] 修正 `seata-http-jakarta`的模块命名和描述 +- [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC协议序列化默认值为protobuf ### refactor: diff --git a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java index 71c9caf8be9..e227d5dc7c7 100644 --- a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java +++ b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java @@ -94,7 +94,8 @@ public void onDataRead(ChannelHandlerContext ctx, Http2DataFrame msg) throws Exc bodyBytes = compressor.decompress(bodyBytes); } String codecValue = headMap.get(GrpcHeaderEnum.CODEC_TYPE.header); - int codec = Integer.parseInt(codecValue); + int codec = StringUtils.isBlank(codecValue) ? SerializerType.PROTOBUF.getCode() + : Integer.parseInt(codecValue); SerializerType serializerType = SerializerType.getByCode(codec); rpcMsg.setCodec(serializerType.getCode()); Serializer serializer = SerializerServiceLoader.load(serializerType); From 60a81b1e93b6e2833df99c89ee21c5687512a2e7 Mon Sep 17 00:00:00 2001 From: yiqi <77573225+PleaseGiveMeTheCoke@users.noreply.github.com> Date: Sun, 10 Nov 2024 21:02:06 +0800 Subject: [PATCH 4/8] feature: add grpc serializer (#6992) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 1 + .../core/rpc/netty/grpc/GrpcDecoder.java | 2 +- .../core/rpc/netty/grpc/GrpcEncoder.java | 4 +- .../seata/core/serializer/SerializerType.java | 9 ++- .../serializer/protobuf/GrpcSerializer.java | 60 +++++++++++++++++++ ...rg.apache.seata.core.serializer.Serializer | 3 +- test/pom.xml | 5 ++ .../core/rpc/netty/mockserver/GrpcTest.java | 13 ++-- ...rg.apache.seata.core.serializer.Serializer | 17 ++++++ 10 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 serializer/seata-serializer-protobuf/src/main/java/org/apache/seata/serializer/protobuf/GrpcSerializer.java create mode 100644 test/src/test/resources/META-INF/services/org.apache.seata.core.serializer.Serializer diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 8ba55503320..cfd89f80cec 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -8,6 +8,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6881](https://github.com/apache/incubator-seata/pull/6881)] support grpc - [[#6864](https://github.com/apache/incubator-seata/pull/6864)] support shentong database - [[#6974](https://github.com/apache/incubator-seata/pull/6974)] support fastjson2 undolog parser +- [[#6992](https://github.com/apache/incubator-seata/pull/6992)] support grpc serializer ### bugfix: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 915a039cbb9..6aeb138b529 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -8,6 +8,7 @@ - [[#6881](https://github.com/apache/incubator-seata/pull/6881)] client和server支持grpc协议 - [[#6864](https://github.com/apache/incubator-seata/pull/6864)] 支持神通数据库(oscar) - [[#6974](https://github.com/apache/incubator-seata/pull/6974)] 支持UndoLog的fastjson2序列化方式 +- [[#6992](https://github.com/apache/incubator-seata/pull/6992)] 支持grpc序列化器 ### bugfix: diff --git a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java index e227d5dc7c7..5544e994a55 100644 --- a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java +++ b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcDecoder.java @@ -94,7 +94,7 @@ public void onDataRead(ChannelHandlerContext ctx, Http2DataFrame msg) throws Exc bodyBytes = compressor.decompress(bodyBytes); } String codecValue = headMap.get(GrpcHeaderEnum.CODEC_TYPE.header); - int codec = StringUtils.isBlank(codecValue) ? SerializerType.PROTOBUF.getCode() + int codec = StringUtils.isBlank(codecValue) ? SerializerType.GRPC.getCode() : Integer.parseInt(codecValue); SerializerType serializerType = SerializerType.getByCode(codec); rpcMsg.setCodec(serializerType.getCode()); diff --git a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcEncoder.java b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcEncoder.java index dbbbfe1be48..2601a2f0a6e 100644 --- a/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcEncoder.java +++ b/core/src/main/java/org/apache/seata/core/rpc/netty/grpc/GrpcEncoder.java @@ -64,14 +64,14 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) ByteString dataBytes; if (messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST && messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE) { - Serializer serializer = SerializerServiceLoader.load(SerializerType.getByCode(SerializerType.PROTOBUF.getCode())); + Serializer serializer = SerializerServiceLoader.load(SerializerType.getByCode(SerializerType.GRPC.getCode())); byte[] serializedBytes = serializer.serialize(body); Compressor compressor = CompressorFactory.getCompressor(rpcMessage.getCompressor()); dataBytes = ByteString.copyFrom(compressor.compress(serializedBytes)); } else { dataBytes = ByteString.EMPTY; } - headMap.put(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.PROTOBUF.getCode())); + headMap.put(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())); headMap.put(GrpcHeaderEnum.COMPRESS_TYPE.header, String.valueOf(rpcMessage.getCompressor())); GrpcMessageProto.Builder builder = GrpcMessageProto.newBuilder() .putAllHeadMap(headMap) diff --git a/core/src/main/java/org/apache/seata/core/serializer/SerializerType.java b/core/src/main/java/org/apache/seata/core/serializer/SerializerType.java index 56fd8136d17..39772b34ce0 100644 --- a/core/src/main/java/org/apache/seata/core/serializer/SerializerType.java +++ b/core/src/main/java/org/apache/seata/core/serializer/SerializerType.java @@ -70,7 +70,14 @@ public enum SerializerType { * Math.pow(2, 6) */ FASTJSON2((byte)0x64), - ; + + + /** + * The grpc + *

+ * Math.pow(2, 7) + */ + GRPC((byte) 0x128); private final byte code; diff --git a/serializer/seata-serializer-protobuf/src/main/java/org/apache/seata/serializer/protobuf/GrpcSerializer.java b/serializer/seata-serializer-protobuf/src/main/java/org/apache/seata/serializer/protobuf/GrpcSerializer.java new file mode 100644 index 00000000000..2ef8eac784e --- /dev/null +++ b/serializer/seata-serializer-protobuf/src/main/java/org/apache/seata/serializer/protobuf/GrpcSerializer.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.seata.serializer.protobuf; + +import com.google.protobuf.Any; +import com.google.protobuf.Message; +import org.apache.seata.common.exception.ShouldNeverHappenException; +import org.apache.seata.common.loader.LoadLevel; +import org.apache.seata.core.serializer.Serializer; +import org.apache.seata.serializer.protobuf.convertor.PbConvertor; +import org.apache.seata.serializer.protobuf.manager.ProtobufConvertManager; + +@LoadLevel(name = "GRPC") +public class GrpcSerializer implements Serializer { + @Override + public byte[] serialize(T t) { + PbConvertor pbConvertor = ProtobufConvertManager.getInstance() + .fetchConvertor(t.getClass().getName()); + Any grpcBody = Any.pack((Message) pbConvertor.convert2Proto(t)); + + return grpcBody.toByteArray(); + } + + @Override + public T deserialize(byte[] bytes) { + try { + Any body = Any.parseFrom(bytes); + final Class clazz = ProtobufConvertManager.getInstance().fetchProtoClass(getTypeNameFromTypeUrl(body.getTypeUrl())); + if (body.is(clazz)) { + Object ob = body.unpack(clazz); + PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchReversedConvertor(clazz.getName()); + + return (T) pbConvertor.convert2Model(ob); + } + } catch (Throwable e) { + throw new ShouldNeverHappenException("GrpcSerializer deserialize error", e); + } + + return null; + } + + private String getTypeNameFromTypeUrl(String typeUri) { + int pos = typeUri.lastIndexOf('/'); + return pos == -1 ? "" : typeUri.substring(pos + 1); + } +} diff --git a/serializer/seata-serializer-protobuf/src/main/resources/META-INF/services/org.apache.seata.core.serializer.Serializer b/serializer/seata-serializer-protobuf/src/main/resources/META-INF/services/org.apache.seata.core.serializer.Serializer index 71098c53674..f6fbf709dea 100644 --- a/serializer/seata-serializer-protobuf/src/main/resources/META-INF/services/org.apache.seata.core.serializer.Serializer +++ b/serializer/seata-serializer-protobuf/src/main/resources/META-INF/services/org.apache.seata.core.serializer.Serializer @@ -14,4 +14,5 @@ # See the License for the specific language governing permissions and # limitations under the License. # -org.apache.seata.serializer.protobuf.ProtobufSerializer \ No newline at end of file +org.apache.seata.serializer.protobuf.ProtobufSerializer +org.apache.seata.serializer.protobuf.GrpcSerializer \ No newline at end of file diff --git a/test/pom.xml b/test/pom.xml index d35f25bad5e..e9991c688db 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -71,6 +71,11 @@ seata-tm ${project.version} + + org.apache.seata + seata-serializer-protobuf + ${project.version} + io.grpc grpc-alts diff --git a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/GrpcTest.java b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/GrpcTest.java index 0d63d2eb70f..042160a9ba2 100644 --- a/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/GrpcTest.java +++ b/test/src/test/java/org/apache/seata/core/rpc/netty/mockserver/GrpcTest.java @@ -16,6 +16,7 @@ */ package org.apache.seata.core.rpc.netty.mockserver; +import com.google.protobuf.Any; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.stub.StreamObserver; @@ -25,6 +26,8 @@ import org.apache.seata.core.protocol.generated.GrpcMessageProto; import org.apache.seata.core.rpc.netty.RmNettyRemotingClient; import org.apache.seata.core.rpc.netty.TmNettyRemotingClient; +import org.apache.seata.core.rpc.netty.grpc.GrpcHeaderEnum; +import org.apache.seata.core.serializer.SerializerType; import org.apache.seata.mockserver.MockServer; import org.apache.seata.serializer.protobuf.generated.*; import org.apache.seata.core.protocol.generated.SeataServiceGrpc; @@ -69,7 +72,7 @@ private GrpcMessageProto getRegisterTMRequest() { .setAbstractIdentifyRequest(abstractIdentifyRequestProto) .build(); - return GrpcMessageProto.newBuilder().setBody(registerTMRequestProto.toByteString()).build(); + return GrpcMessageProto.newBuilder().putHeadMap(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())).setBody(Any.pack(registerTMRequestProto).toByteString()).build(); } private GrpcMessageProto getGlobalBeginRequest() { @@ -77,7 +80,7 @@ private GrpcMessageProto getGlobalBeginRequest() { .setTransactionName("test-transaction") .setTimeout(2000) .build(); - return GrpcMessageProto.newBuilder().setBody(globalBeginRequestProto.toByteString()).build(); + return GrpcMessageProto.newBuilder().putHeadMap(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())).setBody(Any.pack(globalBeginRequestProto).toByteString()).build(); } private GrpcMessageProto getBranchRegisterRequest() { @@ -89,7 +92,7 @@ private GrpcMessageProto getBranchRegisterRequest() { .setApplicationData("{\"mock\":\"mock\"}") .build(); - return GrpcMessageProto.newBuilder().setBody(branchRegisterRequestProto.toByteString()).build(); + return GrpcMessageProto.newBuilder().putHeadMap(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())).setBody(Any.pack(branchRegisterRequestProto).toByteString()).build(); } private GrpcMessageProto getGlobalCommitRequest() { @@ -100,7 +103,7 @@ private GrpcMessageProto getGlobalCommitRequest() { .setAbstractGlobalEndRequest(globalEndRequestProto) .build(); - return GrpcMessageProto.newBuilder().setBody(globalCommitRequestProto.toByteString()).build(); + return GrpcMessageProto.newBuilder().putHeadMap(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())).setBody(Any.pack(globalCommitRequestProto).toByteString()).build(); } private GrpcMessageProto getGlobalRollbackRequest() { @@ -111,7 +114,7 @@ private GrpcMessageProto getGlobalRollbackRequest() { .setAbstractGlobalEndRequest(globalEndRequestProto) .build(); - return GrpcMessageProto.newBuilder().setBody(globalRollbackRequestProto.toByteString()).build(); + return GrpcMessageProto.newBuilder().putHeadMap(GrpcHeaderEnum.CODEC_TYPE.header, String.valueOf(SerializerType.GRPC.getCode())).setBody(Any.pack(globalRollbackRequestProto).toByteString()).build(); } @Test diff --git a/test/src/test/resources/META-INF/services/org.apache.seata.core.serializer.Serializer b/test/src/test/resources/META-INF/services/org.apache.seata.core.serializer.Serializer new file mode 100644 index 00000000000..81c5235e259 --- /dev/null +++ b/test/src/test/resources/META-INF/services/org.apache.seata.core.serializer.Serializer @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +org.apache.seata.serializer.protobuf.GrpcSerializer \ No newline at end of file From 4fae0626a8c9bfe0a48232d4cce00f79c820df2d Mon Sep 17 00:00:00 2001 From: jimin Date: Mon, 11 Nov 2024 12:27:59 +0800 Subject: [PATCH 5/8] optimize: upgrade outdate npmjs dependencies (#6995) --- README.md | 4 +-- changes/en-us/2.x.md | 2 +- changes/zh-cn/2.x.md | 2 +- .../static/console-fe/package-lock.json | 26 +++++++++---------- .../package-lock.json | 20 +++++++------- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 59209dacde9..bb8be9dca08 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Build Status](https://github.com/apache/incubator-seata/workflows/build/badge.svg?branch=develop)](https://github.com/apache/incubator-seata/actions) [![codecov](https://codecov.io/gh/apache/incubator-seata/graph/badge.svg?token=tbmHt2ZfxO)](https://codecov.io/gh/apache/incubator-seata) [![license](https://img.shields.io/github/license/apache/incubator-seata.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) -[![maven](https://img.shields.io/maven-central/v/org.apache.seata/seata-all?versionSuffix=2.1.0)](https://central.sonatype.com/search?q=org.apache.seata%3Aseata-all) +[![maven](https://img.shields.io/maven-central/v/org.apache.seata/seata-all?versionSuffix=2.2.0)](https://central.sonatype.com/search?q=org.apache.seata%3Aseata-all) ## What is Seata? @@ -85,7 +85,7 @@ For more details about principle and design, please go to [Seata wiki page](http Depending on the scenario, choose one of the two dependencies: `org.apache.seata:seata-all` or `org.apache.seata:seata-spring-boot-starter`. ```xml - 2.1.0 + 2.2.0 diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index cfd89f80cec..8e6929e6ce1 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -43,11 +43,11 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] Remove JVM parameter app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] update the naming and description for the `seata-http-jakarta` module - [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC serialization default to Protobuf +- [[#6995](https://github.com/apache/incubator-seata/pull/6995)] upgrade outdate npmjs dependencies ### refactor: -### security: ### test: - [[#6927](https://github.com/apache/incubator-seata/pull/6927)] Add unit tests for the `seata-rocketmq` module diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 6aeb138b529..5b8fa36327c 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -9,7 +9,7 @@ - [[#6864](https://github.com/apache/incubator-seata/pull/6864)] 支持神通数据库(oscar) - [[#6974](https://github.com/apache/incubator-seata/pull/6974)] 支持UndoLog的fastjson2序列化方式 - [[#6992](https://github.com/apache/incubator-seata/pull/6992)] 支持grpc序列化器 - +- [[#6995](https://github.com/apache/incubator-seata/pull/6995)] 升级过时的 npmjs 依赖 ### bugfix: - [[#6899](https://github.com/apache/incubator-seata/pull/6899)] 修复file.conf打包后的读取 diff --git a/console/src/main/resources/static/console-fe/package-lock.json b/console/src/main/resources/static/console-fe/package-lock.json index 1b86e082a97..45ca71e4923 100644 --- a/console/src/main/resources/static/console-fe/package-lock.json +++ b/console/src/main/resources/static/console-fe/package-lock.json @@ -5331,9 +5331,9 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "engines": { "node": ">= 0.6" @@ -6672,9 +6672,9 @@ "integrity": "sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==" }, "node_modules/elliptic": { - "version": "6.5.7", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", - "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz", + "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -8160,9 +8160,9 @@ "dev": true }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -8170,7 +8170,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -9582,9 +9582,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", diff --git a/saga/seata-saga-statemachine-designer/package-lock.json b/saga/seata-saga-statemachine-designer/package-lock.json index 2cb1f08c0d7..d6225eb2023 100644 --- a/saga/seata-saga-statemachine-designer/package-lock.json +++ b/saga/seata-saga-statemachine-designer/package-lock.json @@ -3602,9 +3602,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "engines": { "node": ">= 0.6" @@ -5069,9 +5069,9 @@ } }, "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dev": true, "dependencies": { "accepts": "~1.3.8", @@ -5079,7 +5079,7 @@ "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -5947,9 +5947,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", From 7930f31b0b3810288fb1fed4faae69445b172903 Mon Sep 17 00:00:00 2001 From: GoodBoyCoder Date: Mon, 11 Nov 2024 14:38:54 +0800 Subject: [PATCH 6/8] bugfix: fix the problem of building undoLog exception when update join does not update data (#6994) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 2 ++ .../exec/mysql/MySQLUpdateJoinExecutor.java | 9 +++++- .../exec/UpdateJoinExecutorTest.java | 30 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 8e6929e6ce1..cfbf1cbdd89 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -23,6 +23,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6948](https://github.com/apache/incubator-seata/pull/6948)] Fix the CI build issue on the ARM64 platform - [[#6947](https://github.com/apache/incubator-seata/pull/6947)] fix npe for nacos registry when look up address - [[#6984](https://github.com/apache/incubator-seata/pull/6984)] support building docker image on openjdk23 +- [[#6994](https://github.com/apache/incubator-seata/pull/6994)] fix the problem of building undoLog exception when update join does not update data ### optimize: - [[#6826](https://github.com/apache/incubator-seata/pull/6826)] remove the branch registration operation of the XA read-only transaction diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 5b8fa36327c..f1ce8b59deb 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -23,6 +23,8 @@ - [[#6948](https://github.com/apache/incubator-seata/pull/6948)] 修复在ARM64平台下CI构建出错的问题 - [[#6947](https://github.com/apache/incubator-seata/pull/6947)] 修复nacos注册中心查询可用地址时的空指针问题 - [[#6984](https://github.com/apache/incubator-seata/pull/6984)] 修复 openjdk23 版本下无法构建 docker 镜像的问题 +- [[#6994](https://github.com/apache/incubator-seata/pull/6994)] 修复updateJoin语句未更新到数据时prepareUndoLog异常 + ### optimize: - [[#6826](https://github.com/apache/incubator-seata/pull/6826)] 移除只读XA事务的分支注册操作 diff --git a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java index b682105fa0a..bea122bcb4a 100644 --- a/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java +++ b/rm-datasource/src/main/java/org/apache/seata/rm/datasource/exec/mysql/MySQLUpdateJoinExecutor.java @@ -91,7 +91,11 @@ protected TableRecords beforeImage() throws SQLException { } String selectSQL = buildBeforeImageSQL(joinTable, tableItems[i], suffixCommonCondition, itemTableUpdateColumns); TableRecords tableRecords = buildTableRecords(getTableMeta(tableItems[i]), selectSQL, paramAppenderList); - beforeImagesMap.put(tableItems[i], tableRecords); + if (CollectionUtils.isNotEmpty(tableRecords.getRows())) { + //when building the after image, the table with empty records in before image is skipped + //link issue https://github.com/apache/incubator-seata/issues/6976 + beforeImagesMap.put(tableItems[i], tableRecords); + } } return null; } @@ -231,6 +235,9 @@ private List getItemUpdateColumns(TableMeta itemTableMeta, List @Override protected void prepareUndoLog(TableRecords beforeImage, TableRecords afterImage) throws SQLException { + if (CollectionUtils.isEmpty(beforeImagesMap) && CollectionUtils.isEmpty(afterImagesMap)) { + return; + } if (CollectionUtils.isEmpty(beforeImagesMap) || CollectionUtils.isEmpty(afterImagesMap)) { throw new IllegalStateException("images can not be null"); } diff --git a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java index 3a8ce32ce72..c047decbd94 100644 --- a/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java +++ b/rm-datasource/src/test/java/org/apache/seata/rm/datasource/exec/UpdateJoinExecutorTest.java @@ -76,6 +76,36 @@ public void testUpdateJoinUndoLog() throws SQLException { Assertions.assertDoesNotThrow(()->mySQLUpdateJoinExecutor.prepareUndoLog(beforeImage, afterImage)); } + @Test + public void testEmptyUpdateJoinUndoLog() throws SQLException { + List returnValueColumnLabels = Lists.newArrayList("id", "name"); + Object[][] columnMetas = new Object[][]{ + new Object[]{"", "", "t1", "id", Types.INTEGER, "INTEGER", 64, 0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"}, + new Object[]{"", "", "t1", "name", Types.VARCHAR, "VARCHAR", 64, 0, 10, 0, "", "", 0, 0, 64, 2, "YES", "NO"}, + new Object[]{"", "", "t2", "id", Types.INTEGER, "INTEGER", 64, 0, 10, 1, "", "", 0, 0, 64, 1, "NO", "YES"}, + new Object[]{"", "", "t2", "name", Types.VARCHAR, "VARCHAR", 64, 0, 10, 0, "", "", 0, 0, 64, 2, "YES", "NO"}, + new Object[]{"", "", "t1 inner join t2 on t1.id = t2.id", "id", Types.VARCHAR, "VARCHAR", 64, 0, 10, 0, "", "", 0, 0, 64, 2, "YES", "NO"}, + new Object[]{"", "", "t1 inner join t2 on t1.id = t2.id", "name", Types.VARCHAR, "VARCHAR", 64, 0, 10, 0, "", "", 0, 0, 64, 2, "YES", "NO"}, + }; + Object[][] indexMetas = new Object[][]{ + new Object[]{"PRIMARY", "id", false, "", 3, 1, "A", 34}, + }; + Object[][] beforeReturnValue = new Object[][]{}; + StatementProxy beforeMockStatementProxy = mockStatementProxy(returnValueColumnLabels, beforeReturnValue, columnMetas, indexMetas); + String sql = "update t1 inner join t2 on t1.id = t2.id set t1.name = 'WILL',t2.name = 'WILL'"; + List asts = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL); + MySQLUpdateRecognizer recognizer = new MySQLUpdateRecognizer(sql, asts.get(0)); + UpdateExecutor mySQLUpdateJoinExecutor = new MySQLUpdateJoinExecutor(beforeMockStatementProxy, (statement, args) -> { + return null; + }, recognizer); + TableRecords beforeImage = mySQLUpdateJoinExecutor.beforeImage(); + Object[][] afterReturnValue = new Object[][]{}; + StatementProxy afterMockStatementProxy = mockStatementProxy(returnValueColumnLabels, afterReturnValue, columnMetas, indexMetas); + mySQLUpdateJoinExecutor.statementProxy = afterMockStatementProxy; + TableRecords afterImage = mySQLUpdateJoinExecutor.afterImage(beforeImage); + Assertions.assertDoesNotThrow(()->mySQLUpdateJoinExecutor.prepareUndoLog(beforeImage, afterImage)); + } + private StatementProxy mockStatementProxy(List returnValueColumnLabels, Object[][] returnValue, Object[][] columnMetas, Object[][] indexMetas) { MockDriver mockDriver = new MockDriver(returnValueColumnLabels, returnValue, columnMetas, indexMetas); DruidDataSource dataSource = new DruidDataSource(); From f195eb9dc6664973c2343b3bf6b2652a1ab6e360 Mon Sep 17 00:00:00 2001 From: jimin Date: Thu, 14 Nov 2024 12:04:29 +0800 Subject: [PATCH 7/8] optimize: optimize transaction metrics (#6993) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 1 + .../server/metrics/MeterIdConstants.java | 2 +- .../server/metrics/MetricsSubscriber.java | 155 ++++++++---------- .../seata/server/session/GlobalSession.java | 4 +- .../seata/server/session/SessionHelper.java | 4 +- .../session/SessionStatusValidator.java | 5 + 7 files changed, 82 insertions(+), 90 deletions(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index cfbf1cbdd89..9f5c0cec22e 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -44,6 +44,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] Remove JVM parameter app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] update the naming and description for the `seata-http-jakarta` module - [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC serialization default to Protobuf +- [[#6993](https://github.com/apache/incubator-seata/pull/6993)] optimize transaction metrics - [[#6995](https://github.com/apache/incubator-seata/pull/6995)] upgrade outdate npmjs dependencies diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index f1ce8b59deb..0c2069749c6 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -47,6 +47,7 @@ - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] 移除JVM参数app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] 修正 `seata-http-jakarta`的模块命名和描述 - [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC协议序列化默认值为protobuf +- [[#6993](https://github.com/apache/incubator-seata/pull/6993)] 优化 metrics 指标 ### refactor: diff --git a/server/src/main/java/org/apache/seata/server/metrics/MeterIdConstants.java b/server/src/main/java/org/apache/seata/server/metrics/MeterIdConstants.java index 4babd4ca2e0..18787594f8f 100644 --- a/server/src/main/java/org/apache/seata/server/metrics/MeterIdConstants.java +++ b/server/src/main/java/org/apache/seata/server/metrics/MeterIdConstants.java @@ -85,7 +85,7 @@ public interface MeterIdConstants { .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER) .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED); - Id TIMER_ROLLBACK = new Id(IdConstants.SEATA_TRANSACTION) + Id TIMER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION) .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC) .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER) .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED); diff --git a/server/src/main/java/org/apache/seata/server/metrics/MetricsSubscriber.java b/server/src/main/java/org/apache/seata/server/metrics/MetricsSubscriber.java index 8beed4ba543..2a937d0b98c 100644 --- a/server/src/main/java/org/apache/seata/server/metrics/MetricsSubscriber.java +++ b/server/src/main/java/org/apache/seata/server/metrics/MetricsSubscriber.java @@ -25,6 +25,7 @@ import org.apache.seata.core.event.ExceptionEvent; import org.apache.seata.core.event.GlobalTransactionEvent; import org.apache.seata.core.model.GlobalStatus; +import org.apache.seata.metrics.Id; import org.apache.seata.metrics.registry.Registry; import org.apache.seata.server.event.EventBusManager; import org.slf4j.Logger; @@ -48,21 +49,45 @@ public class MetricsSubscriber { public MetricsSubscriber(Registry registry) { this.registry = registry; - consumers = new HashMap<>(); - consumers.put(GlobalStatus.Begin.name(), this::processGlobalStatusBegin); - consumers.put(GlobalStatus.Committed.name(), this::processGlobalStatusCommitted); - consumers.put(GlobalStatus.Rollbacked.name(), this::processGlobalStatusRollbacked); + this.consumers = initializeConsumers(); + } + + private Map> initializeConsumers() { + Map> consumerMap = new HashMap<>(); + consumerMap.put(GlobalStatus.Begin.name(), this::processGlobalStatusBegin); + consumerMap.put(GlobalStatus.Committed.name(), this::processGlobalStatusCommitted); + consumerMap.put(GlobalStatus.Rollbacked.name(), this::processGlobalStatusRollbacked); + + consumerMap.put(GlobalStatus.CommitFailed.name(), this::processGlobalStatusCommitFailed); + consumerMap.put(GlobalStatus.RollbackFailed.name(), this::processGlobalStatusRollbackFailed); + consumerMap.put(GlobalStatus.TimeoutRollbacked.name(), this::processGlobalStatusTimeoutRollbacked); + consumerMap.put(GlobalStatus.TimeoutRollbackFailed.name(), this::processGlobalStatusTimeoutRollbackFailed); + + consumerMap.put(GlobalStatus.CommitRetryTimeout.name(), this::processGlobalStatusCommitRetryTimeout); + consumerMap.put(GlobalStatus.RollbackRetryTimeout.name(), this::processGlobalStatusTimeoutRollbackRetryTimeout); + + consumerMap.put(STATUS_VALUE_AFTER_COMMITTED_KEY, this::processAfterGlobalCommitted); + consumerMap.put(STATUS_VALUE_AFTER_ROLLBACKED_KEY, this::processAfterGlobalRollbacked); + return consumerMap; + } - consumers.put(GlobalStatus.CommitFailed.name(), this::processGlobalStatusCommitFailed); - consumers.put(GlobalStatus.RollbackFailed.name(), this::processGlobalStatusRollbackFailed); - consumers.put(GlobalStatus.TimeoutRollbacked.name(), this::processGlobalStatusTimeoutRollbacked); - consumers.put(GlobalStatus.TimeoutRollbackFailed.name(), this::processGlobalStatusTimeoutRollbackFailed); + private void increaseCounter(Id counterId, GlobalTransactionEvent event) { + registry.getCounter(counterId.withTag(APP_ID_KEY, event.getApplicationId()) + .withTag(GROUP_KEY, event.getGroup())).increase(1); + } + private void decreaseCounter(Id counterId, GlobalTransactionEvent event) { + registry.getCounter(counterId.withTag(APP_ID_KEY, event.getApplicationId()) + .withTag(GROUP_KEY, event.getGroup())).decrease(1); + } - consumers.put(GlobalStatus.CommitRetryTimeout.name(), this::processGlobalStatusCommitRetryTimeout); - consumers.put(GlobalStatus.RollbackRetryTimeout.name(), this::processGlobalStatusTimeoutRollbackRetryTimeout); + private void increaseSummary(Id summaryId, GlobalTransactionEvent event, long value) { + registry.getSummary( + summaryId.withTag(APP_ID_KEY, event.getApplicationId()).withTag(GROUP_KEY, event.getGroup())).increase(value); + } - consumers.put(STATUS_VALUE_AFTER_COMMITTED_KEY, this::processAfterGlobalCommitted); - consumers.put(STATUS_VALUE_AFTER_ROLLBACKED_KEY, this::processAfterGlobalRollbacked); + private void increaseTimer(Id timerId, GlobalTransactionEvent event) { + registry.getTimer( + timerId.withTag(APP_ID_KEY, event.getApplicationId()).withTag(GROUP_KEY, event.getGroup())).record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); } private void processGlobalStatusBegin(GlobalTransactionEvent event) { @@ -72,124 +97,84 @@ private void processGlobalStatusBegin(GlobalTransactionEvent event) { LOGGER.debug("subscribe:{},threadName:{}", object.toString(), Thread.currentThread().getName()); } } - registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); + increaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); } private void processGlobalStatusCommitted(GlobalTransactionEvent event) { if (event.isRetryGlobal()) { return; } - decreaseActive(event); - registry.getCounter(MeterIdConstants.COUNTER_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getSummary(MeterIdConstants.SUMMARY_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getTimer(MeterIdConstants.TIMER_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())) - .record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); + increaseCounter(MeterIdConstants.COUNTER_COMMITTED, event); + increaseSummary(MeterIdConstants.SUMMARY_COMMITTED, event, 1); + increaseTimer(MeterIdConstants.TIMER_COMMITTED, event); } private void processGlobalStatusRollbacked(GlobalTransactionEvent event) { if (event.isRetryGlobal()) { return; } - decreaseActive(event); - registry.getCounter(MeterIdConstants.COUNTER_ROLLBACKED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getSummary(MeterIdConstants.SUMMARY_ROLLBACKED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getTimer(MeterIdConstants.TIMER_ROLLBACK - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())) - .record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); + increaseCounter(MeterIdConstants.COUNTER_ROLLBACKED, event); + increaseSummary(MeterIdConstants.SUMMARY_ROLLBACKED, event, 1); + increaseTimer(MeterIdConstants.TIMER_ROLLBACKED, event); } private void processAfterGlobalRollbacked(GlobalTransactionEvent event) { if (event.isRetryGlobal() && event.isRetryBranch()) { - decreaseActive(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); } - registry.getCounter(MeterIdConstants.COUNTER_AFTER_ROLLBACKED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getSummary(MeterIdConstants.SUMMARY_AFTER_ROLLBACKED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getTimer(MeterIdConstants.TIMER_AFTER_ROLLBACKED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())) - .record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); + increaseCounter(MeterIdConstants.COUNTER_AFTER_ROLLBACKED, event); + increaseSummary(MeterIdConstants.SUMMARY_AFTER_ROLLBACKED, event, 1); + increaseTimer(MeterIdConstants.TIMER_AFTER_ROLLBACKED, event); } private void processAfterGlobalCommitted(GlobalTransactionEvent event) { if (event.isRetryGlobal() && event.isRetryBranch()) { - decreaseActive(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); } - registry.getCounter(MeterIdConstants.COUNTER_AFTER_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getSummary(MeterIdConstants.SUMMARY_AFTER_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getTimer(MeterIdConstants.TIMER_AFTER_COMMITTED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())) - .record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); + increaseCounter(MeterIdConstants.COUNTER_AFTER_COMMITTED, event); + increaseSummary(MeterIdConstants.SUMMARY_AFTER_COMMITTED, event, 1); + increaseTimer(MeterIdConstants.TIMER_AFTER_COMMITTED, event); } private void processGlobalStatusCommitFailed(GlobalTransactionEvent event) { - decreaseActive(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); reportFailed(event); } private void processGlobalStatusRollbackFailed(GlobalTransactionEvent event) { - decreaseActive(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); reportFailed(event); } private void processGlobalStatusTimeoutRollbacked(GlobalTransactionEvent event) { - decreaseActive(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); } private void processGlobalStatusTimeoutRollbackFailed(GlobalTransactionEvent event) { - decreaseActive(event); - reportTwoPhaseTimeout(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); + increaseSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT, event, 1); + reportFailed(event); } private void processGlobalStatusCommitRetryTimeout(GlobalTransactionEvent event) { - decreaseActive(event); - reportTwoPhaseTimeout(event); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); + increaseSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT, event, 1); + //The phase 2 retry timeout state should be considered a transaction failed + reportFailed(event); } private void processGlobalStatusTimeoutRollbackRetryTimeout(GlobalTransactionEvent event) { - decreaseActive(event); - } - - private void decreaseActive(GlobalTransactionEvent event) { - registry.getCounter(MeterIdConstants.COUNTER_ACTIVE - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).decrease(1); + decreaseCounter(MeterIdConstants.COUNTER_ACTIVE, event); + increaseSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT, event, 1); + //The phase 2 retry timeout state should be considered a transaction failed + reportFailed(event); } private void reportFailed(GlobalTransactionEvent event) { - registry.getSummary(MeterIdConstants.SUMMARY_FAILED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); - registry.getTimer(MeterIdConstants.TIMER_FAILED - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())) - .record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS); - } - - private void reportTwoPhaseTimeout(GlobalTransactionEvent event) { - registry.getSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT - .withTag(APP_ID_KEY, event.getApplicationId()) - .withTag(GROUP_KEY, event.getGroup())).increase(1); + increaseSummary(MeterIdConstants.SUMMARY_FAILED, event, 1); + increaseTimer(MeterIdConstants.TIMER_FAILED, event); } diff --git a/server/src/main/java/org/apache/seata/server/session/GlobalSession.java b/server/src/main/java/org/apache/seata/server/session/GlobalSession.java index 8cfc0ecbc67..251b9876e5b 100644 --- a/server/src/main/java/org/apache/seata/server/session/GlobalSession.java +++ b/server/src/main/java/org/apache/seata/server/session/GlobalSession.java @@ -33,6 +33,7 @@ import org.apache.seata.common.XID; import org.apache.seata.common.util.BufferUtils; import org.apache.seata.common.util.StringUtils; +import org.apache.seata.common.util.UUIDGenerator; import org.apache.seata.config.ConfigurationFactory; import org.apache.seata.core.exception.GlobalTransactionException; import org.apache.seata.core.exception.TransactionException; @@ -41,7 +42,6 @@ import org.apache.seata.core.model.BranchType; import org.apache.seata.core.model.GlobalStatus; import org.apache.seata.core.model.LockStatus; -import org.apache.seata.common.util.UUIDGenerator; import org.apache.seata.server.cluster.raft.RaftServerManager; import org.apache.seata.server.lock.LockerManagerFactory; import org.apache.seata.server.store.SessionStorable; @@ -793,7 +793,7 @@ public void queueToRetryCommit() throws TransactionException { public void queueToRetryRollback() throws TransactionException { GlobalStatus currentStatus = this.getStatus(); GlobalStatus newStatus; - if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) { + if (GlobalStatus.TimeoutRollbacking == currentStatus) { newStatus = GlobalStatus.TimeoutRollbackRetrying; } else { newStatus = GlobalStatus.RollbackRetrying; diff --git a/server/src/main/java/org/apache/seata/server/session/SessionHelper.java b/server/src/main/java/org/apache/seata/server/session/SessionHelper.java index 7ffab5f14be..17cd084505e 100644 --- a/server/src/main/java/org/apache/seata/server/session/SessionHelper.java +++ b/server/src/main/java/org/apache/seata/server/session/SessionHelper.java @@ -212,7 +212,7 @@ public static void endRollbacked(GlobalSession globalSession, boolean retryGloba boolean retryBranch = currentStatus == GlobalStatus.TimeoutRollbackRetrying || currentStatus == GlobalStatus.RollbackRetrying; if (!currentStatus.equals(GlobalStatus.TimeoutRollbacked) - && SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) { + && SessionStatusValidator.isTimeoutRollbacking(currentStatus)) { globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbacked); } else if (!globalSession.getStatus().equals(GlobalStatus.Rollbacked)) { globalSession.changeGlobalStatus(GlobalStatus.Rollbacked); @@ -255,7 +255,7 @@ public static void endRollbackFailed(GlobalSession globalSession, boolean retryG GlobalStatus currentStatus = globalSession.getStatus(); if (isRetryTimeout) { globalSession.changeGlobalStatus(GlobalStatus.RollbackRetryTimeout); - } else if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) { + } else if (SessionStatusValidator.isTimeoutRollbacking(currentStatus)) { globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbackFailed); } else { globalSession.changeGlobalStatus(GlobalStatus.RollbackFailed); diff --git a/server/src/main/java/org/apache/seata/server/session/SessionStatusValidator.java b/server/src/main/java/org/apache/seata/server/session/SessionStatusValidator.java index 52722a76d36..654af466245 100644 --- a/server/src/main/java/org/apache/seata/server/session/SessionStatusValidator.java +++ b/server/src/main/java/org/apache/seata/server/session/SessionStatusValidator.java @@ -36,6 +36,11 @@ public static boolean isTimeoutGlobalStatus(GlobalStatus status) { || status == GlobalStatus.TimeoutRollbackRetrying; } + public static boolean isTimeoutRollbacking(GlobalStatus status) { + return status == GlobalStatus.TimeoutRollbacking + || status == GlobalStatus.TimeoutRollbackRetrying; + } + /** * is rollback global status * From dbe095a39c9f751bcba293feee6234380d4bc58c Mon Sep 17 00:00:00 2001 From: jimin Date: Fri, 15 Nov 2024 09:32:25 +0800 Subject: [PATCH 8/8] optimize: optimize lock release logic in AT transaction mode (#6996) --- changes/en-us/2.x.md | 1 + changes/zh-cn/2.x.md | 2 + .../seata/common/ConfigurationKeys.java | 6 + .../apache/seata/common/DefaultValues.java | 189 +++++++++++++++++- script/config-center/config.txt | 2 +- .../coordinator/DefaultCoordinator.java | 25 ++- .../seata/server/coordinator/DefaultCore.java | 8 +- .../session/AbstractSessionManager.java | 11 + .../main/resources/application.example.yml | 2 +- 9 files changed, 225 insertions(+), 21 deletions(-) diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md index 9f5c0cec22e..22a961edcae 100644 --- a/changes/en-us/2.x.md +++ b/changes/en-us/2.x.md @@ -46,6 +46,7 @@ Add changes here for all PR submitted to the 2.x branch. - [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC serialization default to Protobuf - [[#6993](https://github.com/apache/incubator-seata/pull/6993)] optimize transaction metrics - [[#6995](https://github.com/apache/incubator-seata/pull/6995)] upgrade outdate npmjs dependencies +- [[#6996](https://github.com/apache/incubator-seata/pull/6996)] optimize lock release logic in AT transaction mode ### refactor: diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md index 0c2069749c6..89bfb6438f6 100644 --- a/changes/zh-cn/2.x.md +++ b/changes/zh-cn/2.x.md @@ -47,8 +47,10 @@ - [[#6950](https://github.com/apache/incubator-seata/pull/6950)] 移除JVM参数app.id - [[#6959](https://github.com/apache/incubator-seata/pull/6959)] 修正 `seata-http-jakarta`的模块命名和描述 - [[#6991](https://github.com/apache/incubator-seata/pull/6991)] gRPC协议序列化默认值为protobuf +- [[#6996](https://github.com/apache/incubator-seata/pull/6996)] 优化 AT 事务模式锁释放逻辑 - [[#6993](https://github.com/apache/incubator-seata/pull/6993)] 优化 metrics 指标 + ### refactor: diff --git a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java index ff8436b6dc9..ef7304b1623 100644 --- a/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java +++ b/common/src/main/java/org/apache/seata/common/ConfigurationKeys.java @@ -504,9 +504,15 @@ public interface ConfigurationKeys { /** * The constant ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE. + * This configuration is deprecated, please use {@link #ROLLBACK_FAILED_UNLOCK_ENABLE} instead. */ + @Deprecated String ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE = SERVER_PREFIX + "rollbackRetryTimeoutUnlockEnable"; + /** + * The constant ROLLBACK_FAILED_UNLOCK_ENABLE. + */ + String ROLLBACK_FAILED_UNLOCK_ENABLE = SERVER_PREFIX + "rollbackFailedUnlockEnable"; /** * the constant RETRY_DEAD_THRESHOLD */ diff --git a/common/src/main/java/org/apache/seata/common/DefaultValues.java b/common/src/main/java/org/apache/seata/common/DefaultValues.java index eb0d40bb308..68d06a76ff8 100644 --- a/common/src/main/java/org/apache/seata/common/DefaultValues.java +++ b/common/src/main/java/org/apache/seata/common/DefaultValues.java @@ -18,56 +18,160 @@ import java.time.Duration; +/** + * The interface Default values. + */ public interface DefaultValues { + /** + * The constant DEFAULT_CLIENT_LOCK_RETRY_INTERVAL. + */ int DEFAULT_CLIENT_LOCK_RETRY_INTERVAL = 10; + /** + * The constant DEFAULT_TM_DEGRADE_CHECK_ALLOW_TIMES. + */ int DEFAULT_TM_DEGRADE_CHECK_ALLOW_TIMES = 10; + /** + * The constant DEFAULT_CLIENT_LOCK_RETRY_TIMES. + */ int DEFAULT_CLIENT_LOCK_RETRY_TIMES = 30; + /** + * The constant DEFAULT_CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT. + */ boolean DEFAULT_CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT = true; + /** + * The constant DEFAULT_LOG_EXCEPTION_RATE. + */ int DEFAULT_LOG_EXCEPTION_RATE = 100; + /** + * The constant DEFAULT_CLIENT_ASYNC_COMMIT_BUFFER_LIMIT. + */ int DEFAULT_CLIENT_ASYNC_COMMIT_BUFFER_LIMIT = 10000; + /** + * The constant DEFAULT_TM_DEGRADE_CHECK_PERIOD. + */ int DEFAULT_TM_DEGRADE_CHECK_PERIOD = 2000; + /** + * The constant DEFAULT_CLIENT_REPORT_RETRY_COUNT. + */ int DEFAULT_CLIENT_REPORT_RETRY_COUNT = 5; + /** + * The constant DEFAULT_CLIENT_REPORT_SUCCESS_ENABLE. + */ boolean DEFAULT_CLIENT_REPORT_SUCCESS_ENABLE = false; + /** + * The constant DEFAULT_CLIENT_TABLE_META_CHECK_ENABLE. + */ boolean DEFAULT_CLIENT_TABLE_META_CHECK_ENABLE = true; + /** + * The constant DEFAULT_TABLE_META_CHECKER_INTERVAL. + */ long DEFAULT_TABLE_META_CHECKER_INTERVAL = 60000L; + /** + * The constant DEFAULT_TM_DEGRADE_CHECK. + */ boolean DEFAULT_TM_DEGRADE_CHECK = false; + /** + * The constant DEFAULT_CLIENT_SAGA_BRANCH_REGISTER_ENABLE. + */ boolean DEFAULT_CLIENT_SAGA_BRANCH_REGISTER_ENABLE = false; /** * The default session store dir */ String DEFAULT_SESSION_STORE_FILE_DIR = "sessionStore"; + /** + * The constant DEFAULT_CLIENT_SAGA_RETRY_PERSIST_MODE_UPDATE. + */ boolean DEFAULT_CLIENT_SAGA_RETRY_PERSIST_MODE_UPDATE = false; + /** + * The constant DEFAULT_CLIENT_SAGA_COMPENSATE_PERSIST_MODE_UPDATE. + */ boolean DEFAULT_CLIENT_SAGA_COMPENSATE_PERSIST_MODE_UPDATE = false; + /** + * The constant DEFAULT_RAFT_SERIALIZATION. + */ String DEFAULT_RAFT_SERIALIZATION = "jackson"; + /** + * The constant DEFAULT_RAFT_COMPRESSOR. + */ String DEFAULT_RAFT_COMPRESSOR = "none"; /** * Shutdown timeout default 3s */ int DEFAULT_SHUTDOWN_TIMEOUT_SEC = 13; + /** + * The constant DEFAULT_SELECTOR_THREAD_SIZE. + */ int DEFAULT_SELECTOR_THREAD_SIZE = 1; + /** + * The constant DEFAULT_BOSS_THREAD_SIZE. + */ int DEFAULT_BOSS_THREAD_SIZE = 1; - + /** + * The constant DEFAULT_SELECTOR_THREAD_PREFIX. + */ String DEFAULT_SELECTOR_THREAD_PREFIX = "NettyClientSelector"; + /** + * The constant DEFAULT_WORKER_THREAD_PREFIX. + */ String DEFAULT_WORKER_THREAD_PREFIX = "NettyClientWorkerThread"; + /** + * The constant DEFAULT_ENABLE_CLIENT_BATCH_SEND_REQUEST. + */ @Deprecated boolean DEFAULT_ENABLE_CLIENT_BATCH_SEND_REQUEST = true; + /** + * The constant DEFAULT_ENABLE_TM_CLIENT_BATCH_SEND_REQUEST. + */ boolean DEFAULT_ENABLE_TM_CLIENT_BATCH_SEND_REQUEST = false; + /** + * The constant DEFAULT_ENABLE_RM_CLIENT_BATCH_SEND_REQUEST. + */ boolean DEFAULT_ENABLE_RM_CLIENT_BATCH_SEND_REQUEST = true; + /** + * The constant DEFAULT_ENABLE_TC_SERVER_BATCH_SEND_RESPONSE. + */ boolean DEFAULT_ENABLE_TC_SERVER_BATCH_SEND_RESPONSE = false; + /** + * The constant DEFAULT_CLIENT_CHANNEL_CHECK_FAIL_FAST. + */ boolean DEFAULT_CLIENT_CHANNEL_CHECK_FAIL_FAST = true; + /** + * The constant DEFAULT_BOSS_THREAD_PREFIX. + */ String DEFAULT_BOSS_THREAD_PREFIX = "NettyBoss"; + /** + * The constant DEFAULT_NIO_WORKER_THREAD_PREFIX. + */ String DEFAULT_NIO_WORKER_THREAD_PREFIX = "NettyServerNIOWorker"; + /** + * The constant DEFAULT_EXECUTOR_THREAD_PREFIX. + */ String DEFAULT_EXECUTOR_THREAD_PREFIX = "NettyServerBizHandler"; + /** + * The constant DEFAULT_PROTOCOL. + */ String DEFAULT_PROTOCOL = "seata"; + /** + * The constant DEFAULT_TRANSPORT_HEARTBEAT. + */ boolean DEFAULT_TRANSPORT_HEARTBEAT = true; + /** + * The constant DEFAULT_TRANSACTION_UNDO_DATA_VALIDATION. + */ boolean DEFAULT_TRANSACTION_UNDO_DATA_VALIDATION = true; + /** + * The constant DEFAULT_TRANSACTION_UNDO_LOG_SERIALIZATION. + */ String DEFAULT_TRANSACTION_UNDO_LOG_SERIALIZATION = "jackson"; + /** + * The constant DEFAULT_ONLY_CARE_UPDATE_COLUMNS. + */ boolean DEFAULT_ONLY_CARE_UPDATE_COLUMNS = true; /** * The constant DEFAULT_TRANSACTION_UNDO_LOG_TABLE. @@ -93,40 +197,97 @@ public interface DefaultValues { */ String DEFAULT_DISTRIBUTED_LOCK_DB_TABLE = "distributed_lock"; + /** + * The constant DEFAULT_TM_COMMIT_RETRY_COUNT. + */ int DEFAULT_TM_COMMIT_RETRY_COUNT = 5; + /** + * The constant DEFAULT_TM_ROLLBACK_RETRY_COUNT. + */ int DEFAULT_TM_ROLLBACK_RETRY_COUNT = 5; + /** + * The constant DEFAULT_GLOBAL_TRANSACTION_TIMEOUT. + */ int DEFAULT_GLOBAL_TRANSACTION_TIMEOUT = 60000; + /** + * The constant DEFAULT_TX_GROUP. + */ String DEFAULT_TX_GROUP = "default_tx_group"; + /** + * The constant DEFAULT_TX_GROUP_OLD. + */ @Deprecated String DEFAULT_TX_GROUP_OLD = "my_test_tx_group"; + /** + * The constant DEFAULT_TC_CLUSTER. + */ String DEFAULT_TC_CLUSTER = "default"; + /** + * The constant DEFAULT_GROUPLIST. + */ String DEFAULT_GROUPLIST = "127.0.0.1:8091"; + /** + * The constant DEFAULT_DATA_SOURCE_PROXY_MODE. + */ String DEFAULT_DATA_SOURCE_PROXY_MODE = "AT"; + /** + * The constant DEFAULT_DISABLE_GLOBAL_TRANSACTION. + */ boolean DEFAULT_DISABLE_GLOBAL_TRANSACTION = false; + /** + * The constant SERVICE_DEFAULT_PORT. + */ //currently not use and will be delete in the next version @Deprecated int SERVICE_DEFAULT_PORT = 8091; + /** + * The constant SERVICE_OFFSET_SPRING_BOOT. + */ int SERVICE_OFFSET_SPRING_BOOT = 1000; + /** + * The constant SERVER_PORT. + */ String SERVER_PORT = "seata.server.port"; + /** + * The constant SERVER_DEFAULT_STORE_MODE. + */ String SERVER_DEFAULT_STORE_MODE = "file"; + /** + * The constant DEFAULT_SAGA_JSON_PARSER. + */ String DEFAULT_SAGA_JSON_PARSER = "fastjson"; + /** + * The constant DEFAULT_TCC_BUSINESS_ACTION_CONTEXT_JSON_PARSER. + */ // default tcc business action context json parser String DEFAULT_TCC_BUSINESS_ACTION_CONTEXT_JSON_PARSER = "fastjson"; + /** + * The constant DEFAULT_SERVER_ENABLE_CHECK_AUTH. + */ boolean DEFAULT_SERVER_ENABLE_CHECK_AUTH = true; + /** + * The constant DEFAULT_LOAD_BALANCE. + */ String DEFAULT_LOAD_BALANCE = "XID"; + /** + * The constant VIRTUAL_NODES_DEFAULT. + */ int VIRTUAL_NODES_DEFAULT = 10; + /** + * The constant DEFAULT_SEATA_GROUP. + */ String DEFAULT_SEATA_GROUP = "default"; /** @@ -144,7 +305,6 @@ public interface DefaultValues { */ String DEFAULT_CLIENT_UNDO_COMPRESS_THRESHOLD = "64k"; - /** * the constant DEFAULT_RETRY_DEAD_THRESHOLD */ @@ -283,9 +443,9 @@ public interface DefaultValues { long DEFAULT_MAX_ROLLBACK_RETRY_TIMEOUT = -1L; /** - * the const DEFAULT_ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE + * The constant DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE. */ - boolean DEFAULT_ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE = false; + boolean DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE = false; /** * DEFAULT_DISTRIBUTED_LOCK_EXPIRE_TIME @@ -297,16 +457,34 @@ public interface DefaultValues { */ boolean DEFAULT_ENABLE_BRANCH_ASYNC_REMOVE = false; + /** + * The constant DEFAULT_DB_MAX_CONN. + */ int DEFAULT_DB_MAX_CONN = 100; + /** + * The constant DEFAULT_DB_MIN_CONN. + */ int DEFAULT_DB_MIN_CONN = 10; + /** + * The constant DEFAULT_REDIS_MAX_IDLE. + */ int DEFAULT_REDIS_MAX_IDLE = 100; + /** + * The constant DEFAULT_REDIS_MAX_TOTAL. + */ int DEFAULT_REDIS_MAX_TOTAL = 100; + /** + * The constant DEFAULT_REDIS_MIN_IDLE. + */ int DEFAULT_REDIS_MIN_IDLE = 10; + /** + * The constant DEFAULT_QUERY_LIMIT. + */ int DEFAULT_QUERY_LIMIT = 1000; /** @@ -314,5 +492,8 @@ public interface DefaultValues { */ String DRUID_LOCATION = "lib/sqlparser/druid.jar"; + /** + * The constant DEFAULT_ROCKET_MQ_MSG_TIMEOUT. + */ int DEFAULT_ROCKET_MQ_MSG_TIMEOUT = 60 * 1000; } diff --git a/script/config-center/config.txt b/script/config-center/config.txt index 8cf986f3f94..af831bc5d23 100644 --- a/script/config-center/config.txt +++ b/script/config-center/config.txt @@ -140,7 +140,7 @@ server.recovery.rollbackingRetryPeriod=1000 server.recovery.timeoutRetryPeriod=1000 server.maxCommitRetryTimeout=-1 server.maxRollbackRetryTimeout=-1 -server.rollbackRetryTimeoutUnlockEnable=false +server.rollbackFailedUnlockEnable=false server.distributedLockExpireTime=10000 server.session.branchAsyncQueueSize=5000 server.session.enableBranchAsyncRemove=false diff --git a/server/src/main/java/org/apache/seata/server/coordinator/DefaultCoordinator.java b/server/src/main/java/org/apache/seata/server/coordinator/DefaultCoordinator.java index 9003fe268aa..ddfd5f35d66 100644 --- a/server/src/main/java/org/apache/seata/server/coordinator/DefaultCoordinator.java +++ b/server/src/main/java/org/apache/seata/server/coordinator/DefaultCoordinator.java @@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit; import io.netty.channel.Channel; +import org.apache.commons.lang.time.DateFormatUtils; import org.apache.seata.common.DefaultValues; import org.apache.seata.common.thread.NamedThreadFactory; import org.apache.seata.common.util.CollectionUtils; @@ -71,7 +72,6 @@ import org.apache.seata.server.session.SessionHelper; import org.apache.seata.server.session.SessionHolder; import org.apache.seata.server.store.StoreConfig; -import org.apache.commons.lang.time.DateFormatUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; @@ -90,7 +90,7 @@ import static org.apache.seata.common.DefaultValues.DEFAULT_MAX_COMMIT_RETRY_TIMEOUT; import static org.apache.seata.common.DefaultValues.DEFAULT_MAX_ROLLBACK_RETRY_TIMEOUT; import static org.apache.seata.common.DefaultValues.DEFAULT_ROLLBACKING_RETRY_PERIOD; -import static org.apache.seata.common.DefaultValues.DEFAULT_ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE; +import static org.apache.seata.common.DefaultValues.DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE; import static org.apache.seata.common.DefaultValues.DEFAULT_TIMEOUT_RETRY_PERIOD; import static org.apache.seata.common.DefaultValues.DEFAULT_UNDO_LOG_DELETE_PERIOD; @@ -159,7 +159,10 @@ public class DefaultCoordinator extends AbstractTCInboundHandler implements Tran ConfigurationKeys.MAX_ROLLBACK_RETRY_TIMEOUT, DEFAULT_MAX_ROLLBACK_RETRY_TIMEOUT); private static final boolean ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE = ConfigurationFactory.getInstance().getBoolean( - ConfigurationKeys.ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE, DEFAULT_ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE); + ConfigurationKeys.ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE, DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE); + + private static final boolean ROLLBACK_FAILED_UNLOCK_ENABLE = ConfigurationFactory.getInstance().getBoolean( + ConfigurationKeys.ROLLBACK_FAILED_UNLOCK_ENABLE, DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE); private static final int RETRY_DEAD_THRESHOLD = ConfigurationFactory.getInstance() .getInt(org.apache.seata.common.ConfigurationKeys.RETRY_DEAD_THRESHOLD, DefaultValues.DEFAULT_RETRY_DEAD_THRESHOLD); @@ -341,15 +344,15 @@ protected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryRespon protected void timeoutCheck() { SessionCondition sessionCondition = new SessionCondition(GlobalStatus.Begin); sessionCondition.setLazyLoadBranch(true); - Collection beginGlobalsessions = + Collection beginGlobalSessions = SessionHolder.getRootSessionManager().findGlobalSessions(sessionCondition); - if (CollectionUtils.isEmpty(beginGlobalsessions)) { + if (CollectionUtils.isEmpty(beginGlobalSessions)) { return; } - if (!beginGlobalsessions.isEmpty() && LOGGER.isDebugEnabled()) { - LOGGER.debug("Global transaction timeout check begin, size: {}", beginGlobalsessions.size()); + if (!beginGlobalSessions.isEmpty() && LOGGER.isDebugEnabled()) { + LOGGER.debug("Global transaction timeout check begin, size: {}", beginGlobalSessions.size()); } - SessionHelper.forEach(beginGlobalsessions, globalSession -> { + SessionHelper.forEach(beginGlobalSessions, globalSession -> { if (LOGGER.isDebugEnabled()) { LOGGER.debug( globalSession.getXid() + " " + globalSession.getStatus() + " " + globalSession.getBeginTime() + " " @@ -372,7 +375,7 @@ protected void timeoutCheck() { return true; }); }); - if (!beginGlobalsessions.isEmpty() && LOGGER.isDebugEnabled()) { + if (!beginGlobalSessions.isEmpty() && LOGGER.isDebugEnabled()) { LOGGER.debug("Global transaction timeout check end. "); } @@ -394,7 +397,7 @@ protected void handleRetryRollbacking() { SessionHelper.forEach(rollbackingSessions, rollbackingSession -> { try { if (isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT, rollbackingSession.getBeginTime())) { - if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE) { + if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE || ROLLBACK_FAILED_UNLOCK_ENABLE) { rollbackingSession.clean(); } @@ -520,7 +523,7 @@ protected void handleRollbackingByScheduled() { SessionHelper.forEach(needDoRollbackingSessions, rollbackingSession -> { try { if (isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT, rollbackingSession.getBeginTime())) { - if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE) { + if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE || ROLLBACK_FAILED_UNLOCK_ENABLE) { rollbackingSession.clean(); } diff --git a/server/src/main/java/org/apache/seata/server/coordinator/DefaultCore.java b/server/src/main/java/org/apache/seata/server/coordinator/DefaultCore.java index d6c93532fa7..5acbc8988de 100644 --- a/server/src/main/java/org/apache/seata/server/coordinator/DefaultCore.java +++ b/server/src/main/java/org/apache/seata/server/coordinator/DefaultCore.java @@ -57,7 +57,7 @@ public class DefaultCore implements Core { private static final int RETRY_XAER_NOTA_TIMEOUT = ConfigurationFactory.getInstance().getInt(XAER_NOTA_RETRY_TIMEOUT, DefaultValues.DEFAULT_XAER_NOTA_RETRY_TIMEOUT); - private static Map coreMap = new ConcurrentHashMap<>(); + private static final Map CORE_MAP = new ConcurrentHashMap<>(); private static final boolean PARALLEL_HANDLE_BRANCH = ConfigurationFactory.getInstance().getBoolean(ENABLE_PARALLEL_HANDLE_BRANCH_KEY, false); @@ -72,7 +72,7 @@ public DefaultCore(RemotingServer remotingServer) { new Class[] {RemotingServer.class}, new Object[] {remotingServer}); if (CollectionUtils.isNotEmpty(allCore)) { for (AbstractCore core : allCore) { - coreMap.put(core.getHandleBranchType(), core); + CORE_MAP.put(core.getHandleBranchType(), core); } } } @@ -84,7 +84,7 @@ public DefaultCore(RemotingServer remotingServer) { * @return the core */ public AbstractCore getCore(BranchType branchType) { - AbstractCore core = coreMap.get(branchType); + AbstractCore core = CORE_MAP.get(branchType); if (core == null) { throw new NotSupportYetException("unsupported type:" + branchType.name()); } @@ -98,7 +98,7 @@ public AbstractCore getCore(BranchType branchType) { * @param core the core */ public void mockCore(BranchType branchType, AbstractCore core) { - coreMap.put(branchType, core); + CORE_MAP.put(branchType, core); } @Override diff --git a/server/src/main/java/org/apache/seata/server/session/AbstractSessionManager.java b/server/src/main/java/org/apache/seata/server/session/AbstractSessionManager.java index 611993b1594..8b2e7095936 100644 --- a/server/src/main/java/org/apache/seata/server/session/AbstractSessionManager.java +++ b/server/src/main/java/org/apache/seata/server/session/AbstractSessionManager.java @@ -16,6 +16,8 @@ */ package org.apache.seata.server.session; +import org.apache.seata.config.ConfigurationFactory; +import org.apache.seata.core.constants.ConfigurationKeys; import org.apache.seata.core.exception.BranchTransactionException; import org.apache.seata.core.exception.GlobalTransactionException; import org.apache.seata.core.exception.TransactionException; @@ -29,10 +31,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.seata.common.DefaultValues.DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE; + /** * The type Abstract session manager. */ public abstract class AbstractSessionManager implements SessionManager { + boolean rollbackFailedUnlockEnable = ConfigurationFactory.getInstance().getBoolean( + ConfigurationKeys.ROLLBACK_FAILED_UNLOCK_ENABLE, DEFAULT_ROLLBACK_FAILED_UNLOCK_ENABLE); /** * The constant LOGGER. @@ -157,6 +163,11 @@ public void onSuccessEnd(GlobalSession globalSession) throws TransactionExceptio @Override public void onFailEnd(GlobalSession globalSession) throws TransactionException { + if (rollbackFailedUnlockEnable) { + globalSession.clean(); + LOGGER.info("xid:{} fail end and remove lock, transaction:{}", globalSession.getXid(), globalSession); + return; + } LOGGER.info("xid:{} fail end, transaction:{}", globalSession.getXid(), globalSession); } diff --git a/server/src/main/resources/application.example.yml b/server/src/main/resources/application.example.yml index 5d92d069284..059312ae856 100644 --- a/server/src/main/resources/application.example.yml +++ b/server/src/main/resources/application.example.yml @@ -139,7 +139,7 @@ seata: service-port: 8091 #If not configured, the default is '${server.port} + 1000' max-commit-retry-timeout: -1 max-rollback-retry-timeout: -1 - rollback-retry-timeout-unlock-enable: false + rollback-failed-unlock-enable: false enable-check-auth: true enable-parallel-request-handle: true enable-parallel-handle-branch: false