diff --git a/.gitignore b/.gitignore
index 44b06f93f74c2f13f603c08d372ee6f1a9916c5d..53d84ffc74323f35e1256cdc82188e5cc5e7bbd8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ dependency-reduced-pom.xml
 /server/*root.*
 /server/.root.*
 /server/sessionStore/
+/server/db_store/
 /sessionStore/
 
 # system ignore
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5aaf85fc370b5553a6bfe80877b98973d678179f..6f85c4a7ed3ad64371aaa7f5aedeb80ba3e90635 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,31 +1,195 @@
-# Seata
+# Contributing to Seata
 
-## Seata Code Style
-Seata code style Comply with Alibaba Java Coding Guidelines.
+It is warmly welcomed if you have interest to hack on Seata. First, we encourage this kind of willing very much. And here is a list of contributing guide for you.
+
+## Topics
+
+* [Reporting security issues](#reporting-security-issues)
+* [Reporting general issues](#reporting-general-issues)
+* [Code and doc contribution](#code-and-doc-contribution)
+* [Test case contribution](#test-case-contribution)
+* [Engage to help anything](#engage-to-help-anything)
+* [Code Style](#code-style)
+
+## Reporting security issues
+
+Security issues are always treated seriously. As our usual principle, we discourage anyone to spread security issues. If you find a security issue of Seata, please do not discuss it in public and even do not open a public issue. Instead we encourage you to send us a private email to  [dev-seata@googlegroups.com](mailto:dev-seata@googlegroups.com) to report this.
+
+## Reporting general issues
+
+To be honest, we regard every user of Seata as a very kind contributor. After experiencing Seata, you may have some feedback for the project. Then feel free to open an issue via [NEW ISSUE](https://github.com/seata/seata/issues/new/choose).
+
+Since we collaborate project Seata in a distributed way, we appreciate **WELL-WRITTEN**, **DETAILED**, **EXPLICIT** issue reports. To make the communication more efficient, we wish everyone could search if your issue is an existing one in the searching list. If you find it existing, please add your details in comments under the existing issue instead of opening a brand new one.
+
+To make the issue details as standard as possible, we setup an [ISSUE TEMPLATE](./.github/ISSUE_TEMPLATE) for issue reporters. Please **BE SURE** to follow the instructions to fill fields in template.
+
+There are a lot of cases when you could open an issue:
+
+* bug report
+* feature request
+* performance issues
+* feature proposal
+* feature design
+* help wanted
+* doc incomplete
+* test improvement
+* any questions on project
+* and so on
+
+Also we must remind that when filling a new issue, please remember to remove the sensitive data from your post. Sensitive data could be password, secret key, network locations, private business data and so on.
+
+## Code and doc contribution
+
+Every action to make project Seata better is encouraged. On GitHub, every improvement for Seata could be via a PR (short for pull request).
+
+* If you find a typo, try to fix it!
+* If you find a bug, try to fix it!
+* If you find some redundant codes, try to remove them!
+* If you find some test cases missing, try to add them!
+* If you could enhance a feature, please **DO NOT** hesitate!
+* If you find code implicit, try to add comments to make it clear!
+* If you find code ugly, try to refactor that!
+* If you can help to improve documents, it could not be better!
+* If you find document incorrect, just do it and fix that!
+* ...
+
+Actually it is impossible to list them completely. Just remember one principle:
+
+> WE ARE LOOKING FORWARD TO ANY PR FROM YOU.
+
+Since you are ready to improve Seata with a PR, we suggest you could take a look at the PR rules here.
+
+* [Workspace Preparation](#workspace-preparation)
+* [Branch Definition](#branch-definition)
+* [Commit Rules](#commit-rules)
+* [PR Description](#pr-description)
+
+### Workspace Preparation
+
+To put forward a PR, we assume you have registered a GitHub ID. Then you could finish the preparation in the following steps:
+
+1. **FORK** Seata to your repository. To make this work, you just need to click the button Fork in right-left of [seata/seata](https://github.com/seata/seata) main page. Then you will end up with your repository in `https://github.com/<your-username>/seata`, in which `your-username` is your GitHub username.
+
+1. **CLONE** your own repository to develop locally. Use `git clone git@github.com:<your-username>/seata.git` to clone repository to your local machine. Then you can create new branches to finish the change you wish to make.
+
+1. **Set Remote** upstream to be `git@github.com:seata/seata.git` using the following two commands:
+
+```
+git remote add upstream git@github.com:seata/seata.git
+git remote set-url --push upstream no-pushing
+```
+
+With this remote setting, you can check your git remote configuration like this:
+
+```
+$ git remote -v
+origin     git@github.com:<your-username>/seata.git (fetch)
+origin     git@github.com:<your-username>/seata.git (push)
+upstream   git@github.com:seata/seata.git (fetch)
+upstream   no-pushing (push)
+```
+
+Adding this, we can easily synchronize local branches with upstream branches.
+
+### Branch Definition
+
+Right now we assume every contribution via pull request is for [branch develop](https://github.com/seata/seata/tree/develop) in Seata. Before contributing, be aware of branch definition would help a lot.
+
+As a contributor, keep in mind again that every contribution via pull request is for branch develop. While in project Seata, there are several other branches, we generally call them release branches(such as 0.6.0,0.6.1), feature branches, hotfix branches and master branch.
+
+When officially releasing a version, there will be a release branch and named with the version number. 
+
+After the release, we will merge the commit of the release branch into the master branch.
 
-Seata 的编码规范遵从于《阿里巴巴JAVA开发规约》。
+When we find that there is a bug in a certain version, we will decide to fix it in a later version or fix it in a specific hotfix version. When we decide to fix the hotfix version, we will checkout the hotfix branch based on the corresponding release branch, perform code repair and verification, and merge it into the develop branch and the master branch.
+
+For larger features, we will pull out the feature branch for development and verification.
+
+
+### Commit Rules
+
+Actually in Seata, we take two rules serious when committing:
+
+* [Commit Message](#commit-message)
+* [Commit Content](#commit-content)
+
+#### Commit Message
+
+Commit message could help reviewers better understand what is the purpose of submitted PR. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than ambiguous message. In general, we advocate the following commit message type:
+
+* docs: xxxx. For example, "docs: add docs about Seata cluster installation".
+* feature: xxxx.For example, "feature: support oracle in AT mode".
+* bugfix: xxxx. For example, "bugfix: fix panic when input nil parameter".
+* refactor: xxxx. For example, "refactor: simplify to make codes more readable".
+* test: xxx. For example, "test: add unit test case for func InsertIntoArray".
+* other readable and explicit expression ways.
+
+On the other side, we discourage contributors from committing message like the following ways:
+
+* ~~fix bug~~
+* ~~update~~
+* ~~add doc~~
+
+If you get lost, please see [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for a start.
+
+#### Commit Content
+
+Commit content represents all content changes included in one commit. We had better include things in one single commit which could support reviewer's complete review without any other commits' help. In another word, contents in one single commit can pass the CI to avoid code mess. In brief, there are three minor rules for us to keep in mind:
+
+* avoid very large change in a commit;
+* complete and reviewable for each commit.
+* check git config(`user.name`, `user.email`) when committing to ensure that it is associated with your github ID.
+
+
+In addition, in the code change part, we suggest that all contributors should read the [code style of Seata](#code-style).
+
+No matter commit message, or commit content, we do take more emphasis on code review.
+
+
+### PR Description
+
+PR is the only way to make change to Seata project files. To help reviewers better get your purpose, PR description could not be too detailed. We encourage contributors to follow the [PR template](./.github/PULL_REQUEST_TEMPLATE.md) to finish the pull request.
+
+## Test case contribution
+
+Any test case would be welcomed. Currently, Seata function test cases are high priority.
+
+* For unit test, you need to create a test file named `xxxTest.java` in the test directory of the same module. Recommend you to use the junit5 UT framework
+
+* For integration test, you can put the integration test in the test directory or the seata-test module. It is recommended to use the mockito test framework.
+
+## Engage to help anything
+
+We choose GitHub as the primary place for Seata to collaborate. So the latest updates of Seata are always here. Although contributions via PR is an explicit way to help, we still call for any other ways.
+
+* reply to other's issues if you could;
+* help solve other user's problems;
+* help review other's PR design;
+* help review other's codes in PR;
+* discuss about Seata to make things clearer;
+* advocate Seata technology beyond GitHub;
+* write blogs on Seata and so on.
+
+
+## Code Style
+
+Seata code style Comply with Alibaba Java Coding Guidelines.
 
 
 ### Guidelines
 [Alibaba-Java-Coding-Guidelines](https://alibaba.github.io/Alibaba-Java-Coding-Guidelines/) 
 
-[阿里巴巴JAVA开发规约](https://github.com/alibaba/p3c/blob/master/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4Java%E5%BC%80%E5%8F%91%E6%89%8B%E5%86%8C%EF%BC%88%E8%AF%A6%E5%B0%BD%E7%89%88%EF%BC%89.pdf)
-
 
 ### IDE Plugin Install(not necessary)
 
 *It is not necessary to install, if you want to find a problem when you are coding.*
 
-*不是必须安装,如果你需要在开发的时候实时发现问题的话,你需要安装。*
 
 #### idea IDE
 [p3c-idea-plugin-install](https://github.com/alibaba/p3c/blob/master/idea-plugin/README.md) 
 
-[p3c插件idea IDE上安装方法](https://github.com/alibaba/p3c/blob/master/idea-plugin/README_cn.md)
-
 #### eclipse IDE
 [p3c-eclipse-plugin-install](https://github.com/alibaba/p3c/blob/master/eclipse-plugin/README.md)
 
-[p3c插件eclipse IDE上安装方法](https://github.com/alibaba/p3c/blob/master/eclipse-plugin/README_cn.md)
 
-#### Acknowledgement [Alibaba p3c](https://github.com/alibaba/p3c)
\ No newline at end of file
+In a word, **ANY HELP IS CONTRIBUTION.**
\ No newline at end of file
diff --git a/README.md b/README.md
index c60e2268859057b9bfe639348d6c41d09ae1ff95..a1cf0a9f8dd9e103fa31bcb8bef90b7cdbff5e0a 100644
--- a/README.md
+++ b/README.md
@@ -81,7 +81,7 @@ For more details about principle and design, please go to [Seata wiki page](http
 
 ## Maven dependency
 ```xml
-<seata.version>0.6.0</seata.version>
+<seata.version>0.6.1</seata.version>
 
 <dependency>
     <groupId>io.seata</groupId>
diff --git a/all/pom.xml b/all/pom.xml
index 444ef36470371df6bee5493e4d9c7b915741a7f5..7f9a5aebf1cdc2e43f05bf5d9db5d249840b8c6a 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -21,7 +21,7 @@
 
     <groupId>io.seata</groupId>
     <artifactId>seata-all</artifactId>
-    <version>0.6.1</version>
+    <version>0.7.0</version>
 
     <name>Seata All-in-one ${project.version}</name>
     <url>http://seata.io</url>
@@ -207,6 +207,16 @@
             <artifactId>seata-tm</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-codec-seata</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-codec-protobuf</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <!-- spring  -->
         <dependency>
@@ -264,6 +274,10 @@
             <groupId>commons-pool</groupId>
             <artifactId>commons-pool</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo</artifactId>
@@ -376,6 +390,16 @@
             <artifactId>motan-transport-netty</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-runtime</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
@@ -476,6 +500,8 @@
                                     <include>io.seata:seata-spring</include>
                                     <include>io.seata:seata-tcc</include>
                                     <include>io.seata:seata-tm</include>
+                                    <include>io.seata:seata-codec-seata</include>
+                                    <include>io.seata:seata-codec-protobuf</include>
                                 </includes>
                             </artifactSet>
                             <transformers>
diff --git a/bom/pom.xml b/bom/pom.xml
index a2328259cc846977b909fd4807cf8fb73c9ded29..139fe81449280c6ef1817ea17a4fa7200265c5c0 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -20,7 +20,7 @@
 
     <groupId>io.seata</groupId>
     <artifactId>seata-bom</artifactId>
-    <version>0.6.1</version>
+    <version>0.7.0</version>
 
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
@@ -70,6 +70,7 @@
         <dubbo.alibaba.version>2.6.5</dubbo.alibaba.version>
         <sofa.rpc.version>5.5.3</sofa.rpc.version>
         <fastjson.version>1.2.58</fastjson.version>
+        <protostuff.version>1.5.9</protostuff.version>
         <config.version>1.2.1</config.version>
         <slf4j-api.version>1.7.22</slf4j-api.version>
         <logback-classic.version>1.2.0</logback-classic.version>
@@ -103,11 +104,14 @@
         <mysql.client.version>5.1.30</mysql.client.version>
         <h2.version>1.4.181</h2.version>
         <motan.version>1.0.0</motan.version>
+        <jackson.version>2.9.8</jackson.version>
+        <jcommander.version>1.72</jcommander.version>
 
         <!-- Compiler settings properties -->
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <protobuf.version>3.7.1</protobuf.version>
     </properties>
 
     <dependencyManagement>
@@ -142,6 +146,16 @@
                 <artifactId>sofa-rpc-all</artifactId>
                 <version>${sofa.rpc.version}</version>
             </dependency>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-core</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.protostuff</groupId>
+                <artifactId>protostuff-runtime</artifactId>
+                <version>${protostuff.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.typesafe</groupId>
                 <artifactId>config</artifactId>
@@ -172,6 +186,11 @@
                 <artifactId>commons-pool</artifactId>
                 <version>${commons-pool.version}</version>
             </dependency>
+            <dependency>
+                <groupId>com.google.protobuf</groupId>
+                <artifactId>protobuf-java</artifactId>
+                <version>${protobuf.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.dubbo</groupId>
                 <artifactId>dubbo</artifactId>
@@ -343,13 +362,34 @@
                 <groupId>com.weibo</groupId>
                 <artifactId>motan-core</artifactId>
                 <version>${motan.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>slf4j-log4j12</artifactId>
+                        <groupId>org.slf4j</groupId>
+                    </exclusion>
+                </exclusions>
             </dependency>
             <dependency>
                 <groupId>com.weibo</groupId>
                 <artifactId>motan-transport-netty</artifactId>
                 <version>${motan.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>slf4j-log4j12</artifactId>
+                        <groupId>org.slf4j</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-databind</artifactId>
+                <version>${jackson.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.beust</groupId>
+                <artifactId>jcommander</artifactId>
+                <version>${jcommander.version}</version>
             </dependency>
-
         </dependencies>
     </dependencyManagement>
 
diff --git a/codec/pom.xml b/codec/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..faa835bc4c98e6bc11a78c9ed45872c0a813907f
--- /dev/null
+++ b/codec/pom.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.seata</groupId>
+        <artifactId>seata-parent</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>seata-codec</artifactId>
+    <packaging>pom</packaging>
+    <name>seata-codec ${project.version}</name>
+
+    <modules>
+        <module>seata-codec-all</module>
+        <module>seata-codec-protobuf</module>
+        <module>seata-codec-seata</module>
+    </modules>
+
+</project>
diff --git a/codec/seata-codec-all/pom.xml b/codec/seata-codec-all/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f566782c68ac1bbf2f18dba3023ecfad59e32751
--- /dev/null
+++ b/codec/seata-codec-all/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.seata</groupId>
+        <artifactId>seata-codec</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>seata-codec-all</artifactId>
+    <name>seata-codec-all ${project.version}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-codec-seata</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-codec-protobuf</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/codec/seata-codec-protobuf/pom.xml b/codec/seata-codec-protobuf/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..98fdd2c569d44a61983adb68076b93dd23977651
--- /dev/null
+++ b/codec/seata-codec-protobuf/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.seata</groupId>
+        <artifactId>seata-codec</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>seata-codec-protobuf</artifactId>
+    <packaging>jar</packaging>
+    <name>seata-codec-protobuf ${project.version}</name>
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-common</artifactId>
+            <version>${revision}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufCodec.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f3d1eabc131ea66e5099bd6dc9dfee2d841d3bd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufCodec.java
@@ -0,0 +1,82 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+import com.google.protobuf.GeneratedMessageV3;
+import io.seata.codec.protobuf.convertor.PbConvertor;
+import io.seata.codec.protobuf.manager.ProtobufConvertManager;
+import io.seata.common.loader.LoadLevel;
+import io.seata.core.codec.Codec;
+
+/**
+ * The type Protobuf codec.
+ *
+ * @author leizhiyuan
+ * @date 2019 /5/6
+ */
+@LoadLevel(name = "PROTOBUF", order = 0)
+public class ProtobufCodec implements Codec {
+
+    protected static final Charset UTF8 = Charset.forName("utf-8");
+
+    @Override
+    public <T> byte[] encode(T t) {
+        if (t == null) {
+            throw new NullPointerException();
+        }
+
+        //translate to pb
+        final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchConvertor(
+            t.getClass().getName());
+        //for cross language,write FullName to data,which defines in proto file
+        GeneratedMessageV3 newBody = (GeneratedMessageV3)pbConvertor.convert2Proto(t);
+        byte[] body = ProtobufSerializer.serializeContent(newBody);
+        final String name = newBody.getDescriptorForType().getFullName();
+        final byte[] nameBytes = name.getBytes(UTF8);
+        ByteBuffer byteBuffer = ByteBuffer.allocate(4 + nameBytes.length + body.length);
+        byteBuffer.putInt(nameBytes.length);
+        byteBuffer.put(nameBytes);
+        byteBuffer.put(body);
+        byteBuffer.flip();
+        byte[] content = new byte[byteBuffer.limit()];
+        byteBuffer.get(content);
+        return content;
+    }
+
+    @Override
+    public <T> T decode(byte[] bytes) {
+        if (bytes == null) {
+            throw new NullPointerException();
+        }
+        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+        int clazzNameLength = byteBuffer.getInt();
+        byte[] clazzName = new byte[clazzNameLength];
+        byteBuffer.get(clazzName);
+        byte[] body = new byte[bytes.length - clazzNameLength - 4];
+        byteBuffer.get(body);
+        final String descriptorName = new String(clazzName, UTF8);
+        Class protobufClazz = ProtobufConvertManager.getInstance().fetchProtoClass(descriptorName);
+        Object protobufObject = ProtobufSerializer.deserializeContent(protobufClazz.getName(), body);
+        //translate back to core model
+        final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchReversedConvertor(protobufClazz.getName());
+        Object newBody = pbConvertor.convert2Model(protobufObject);
+        return (T)newBody;
+    }
+
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufHelper.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..730350854350ac1c7ff87adbc9606a8d81081cc3
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufHelper.java
@@ -0,0 +1,88 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.google.protobuf.MessageLite;
+import io.seata.common.exception.ShouldNeverHappenException;
+
+/**
+ * @author leizhiyuan
+ */
+public class ProtobufHelper {
+
+    /**
+     * Cache of parseFrom method
+     */
+    ConcurrentMap<Class, Method> parseFromMethodMap = new ConcurrentHashMap<Class, Method>();
+
+    /**
+     * Cache of toByteArray method
+     */
+    ConcurrentMap<Class, Method> toByteArrayMethodMap = new ConcurrentHashMap<Class, Method>();
+
+    /**
+     *  {className:class}
+     */
+    private ConcurrentMap<String, Class> requestClassCache = new ConcurrentHashMap<String, Class>();
+
+    /**
+     *
+     * @param clazzName
+     * @return
+     */
+    public Class getPbClass(String clazzName) {
+        Class reqClass = requestClassCache.get(clazzName);
+        if (reqClass == null) {
+            // 读取接口里的方法参数和返回值
+            Class clazz = null;
+            try {
+                clazz = Class.forName(clazzName);
+            } catch (ClassNotFoundException e) {
+                throw new ShouldNeverHappenException("get class occurs exception", e);
+
+            }
+            loadProtoClassToCache(clazzName, clazz);
+        }
+        return requestClassCache.get(clazzName);
+    }
+
+    /**
+     *
+     * @param key
+     * @param clazz
+     */
+    private void loadProtoClassToCache(String key, Class clazz) {
+        if (clazz == void.class || !isProtoBufMessageClass(clazz)) {
+            throw new ShouldNeverHappenException("class based protobuf: " + clazz.getName()
+                + ", only support return protobuf message!");
+        }
+        requestClassCache.put(key, clazz);
+    }
+
+    /**
+     * Is this class is assignable from MessageLite
+     *
+     * @param clazz unknown class
+     * @return is assignable from MessageLite
+     */
+    boolean isProtoBufMessageClass(Class clazz) {
+        return clazz != null && MessageLite.class.isAssignableFrom(clazz);
+    }
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufSerializer.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..315ba5c00e4c74a2d826ced6ac014ed5ebb4fc81
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/ProtobufSerializer.java
@@ -0,0 +1,93 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import io.seata.common.exception.ShouldNeverHappenException;
+
+/**
+ * @author leizhiyuan
+ */
+public class ProtobufSerializer {
+
+    private static final ProtobufHelper PROTOBUF_HELPER = new ProtobufHelper();
+
+    /**
+     * Encode method name
+     */
+    private static final String METHOD_TOBYTEARRAY = "toByteArray";
+    /**
+     * Decode method name
+     */
+    private static final String METHOD_PARSEFROM = "parseFrom";
+
+    public static byte[] serializeContent(Object request) {
+
+        Class clazz = request.getClass();
+        Method method = PROTOBUF_HELPER.toByteArrayMethodMap.get(clazz);
+        if (method == null) {
+            try {
+                method = clazz.getMethod(METHOD_TOBYTEARRAY);
+                method.setAccessible(true);
+                PROTOBUF_HELPER.toByteArrayMethodMap.put(clazz, method);
+            } catch (Exception e) {
+                throw new ShouldNeverHappenException("Cannot found method " + clazz.getName()
+                    + ".toByteArray(), please check the generated code.", e);
+            }
+        }
+        byte[] bytes = new byte[0];
+        try {
+            bytes = (byte[])method.invoke(request);
+        } catch (Exception e) {
+            throw new ShouldNeverHappenException("serialize occurs exception", e);
+        }
+
+        return bytes;
+    }
+
+    public static <T> T deserializeContent(String responseClazz, byte[] content) {
+        if (content == null || content.length == 0) {
+            return null;
+        }
+        Class clazz = PROTOBUF_HELPER.getPbClass(responseClazz);
+
+        Method method = PROTOBUF_HELPER.parseFromMethodMap.get(clazz);
+        if (method == null) {
+            try {
+                method = clazz.getMethod(METHOD_PARSEFROM, byte[].class);
+                if (!Modifier.isStatic(method.getModifiers())) {
+                    throw new ShouldNeverHappenException("Cannot found static method " + clazz.getName()
+                        + ".parseFrom(byte[]), please check the generated code");
+                }
+                method.setAccessible(true);
+                PROTOBUF_HELPER.parseFromMethodMap.put(clazz, method);
+            } catch (NoSuchMethodException e) {
+                throw new ShouldNeverHappenException("Cannot found method " + clazz.getName()
+                    + ".parseFrom(byte[]), please check the generated code", e);
+            }
+        }
+        Object result;
+        try {
+            result = method.invoke(null, content);
+        } catch (Exception e) {
+            throw new ShouldNeverHappenException("Error when invoke " + clazz.getName() + ".parseFrom(byte[]).", e);
+        }
+
+        return (T)result;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..64bd572c91ec27020c58dfb0fb591459e1d2e816
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertor.java
@@ -0,0 +1,72 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.BranchCommitRequestProto;
+import io.seata.codec.protobuf.generated.BranchTypeProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchCommitRequestConvertor implements PbConvertor<BranchCommitRequest, BranchCommitRequestProto> {
+    @Override
+    public BranchCommitRequestProto convert2Proto(BranchCommitRequest branchCommitRequest) {
+        final short typeCode = branchCommitRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String applicationData = branchCommitRequest.getApplicationData();
+        final AbstractBranchEndRequestProto abstractBranchEndRequestProto = AbstractBranchEndRequestProto
+            .newBuilder().
+                setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setXid(branchCommitRequest.getXid())
+            .setBranchId(branchCommitRequest.getBranchId())
+            .setBranchType(BranchTypeProto.valueOf(branchCommitRequest.getBranchType().name()))
+            .setApplicationData(applicationData==null?"":applicationData)
+            .setResourceId(branchCommitRequest.getResourceId())
+            .build();
+
+        BranchCommitRequestProto result = BranchCommitRequestProto.newBuilder()
+            .setAbstractBranchEndRequest(abstractBranchEndRequestProto)
+            .build();
+        return result;
+    }
+
+    @Override
+    public BranchCommitRequest convert2Model(BranchCommitRequestProto branchCommitRequestProto) {
+        BranchCommitRequest branchCommitRequest = new BranchCommitRequest();
+        branchCommitRequest.setApplicationData(
+            branchCommitRequestProto.getAbstractBranchEndRequest().getApplicationData());
+        branchCommitRequest.setBranchId(branchCommitRequestProto.getAbstractBranchEndRequest().getBranchId());
+        branchCommitRequest.setResourceId(branchCommitRequestProto.getAbstractBranchEndRequest().getResourceId());
+        branchCommitRequest.setXid(branchCommitRequestProto.getAbstractBranchEndRequest().getXid());
+        branchCommitRequest.setBranchType(
+            BranchType.valueOf(branchCommitRequestProto.getAbstractBranchEndRequest().getBranchType().name()));
+
+        return branchCommitRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..545678244f5141ccdd2b191b34fee80c8c8504fd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertor.java
@@ -0,0 +1,90 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.BranchCommitResponseProto;
+import io.seata.codec.protobuf.generated.BranchStatusProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchCommitResponseConvertor implements PbConvertor<BranchCommitResponse, BranchCommitResponseProto> {
+    @Override
+    public BranchCommitResponseProto convert2Proto(BranchCommitResponse branchCommitResponse) {
+        final short typeCode = branchCommitResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = branchCommitResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(branchCommitResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        final AbstractTransactionResponseProto abstractTransactionRequestProto = AbstractTransactionResponseProto
+            .newBuilder()
+            .setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(branchCommitResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        final AbstractBranchEndResponseProto abstractBranchEndResponse = AbstractBranchEndResponseProto
+            .newBuilder().
+                setAbstractTransactionResponse(abstractTransactionRequestProto)
+            .setXid(branchCommitResponse.getXid())
+            .setBranchId(branchCommitResponse.getBranchId())
+            .setBranchStatus(BranchStatusProto.forNumber(branchCommitResponse.getBranchStatus().getCode()))
+            .build();
+
+        BranchCommitResponseProto result = BranchCommitResponseProto.newBuilder()
+            .setAbstractBranchEndResponse(abstractBranchEndResponse)
+            .build();
+        return result;
+    }
+
+    @Override
+    public BranchCommitResponse convert2Model(BranchCommitResponseProto branchCommitResponseProto) {
+
+        BranchCommitResponse branchCommitResponse = new BranchCommitResponse();
+        branchCommitResponse.setBranchId(branchCommitResponseProto.getAbstractBranchEndResponse().getBranchId());
+        branchCommitResponse.setBranchStatus(
+            BranchStatus.get(branchCommitResponseProto.getAbstractBranchEndResponse().getBranchStatusValue()));
+        branchCommitResponse.setXid(branchCommitResponseProto.getAbstractBranchEndResponse().getXid());
+        branchCommitResponse.setMsg(
+            branchCommitResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getAbstractResultMessage().getMsg());
+        branchCommitResponse.setResultCode(ResultCode.valueOf(
+            branchCommitResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getAbstractResultMessage().getResultCode().name()));
+
+        branchCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            branchCommitResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getTransactionExceptionCode().name()));
+        return branchCommitResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe87c5585d7c2270b1771200f8171bb33b4eba1e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertor.java
@@ -0,0 +1,64 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.BranchRegisterRequestProto;
+import io.seata.codec.protobuf.generated.BranchTypeProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRegisterRequestConvertor implements PbConvertor<BranchRegisterRequest, BranchRegisterRequestProto> {
+    @Override
+    public BranchRegisterRequestProto convert2Proto(BranchRegisterRequest branchRegisterRequest) {
+        final short typeCode = branchRegisterRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String applicationData = branchRegisterRequest.getApplicationData();
+        final String resourceId = branchRegisterRequest.getResourceId();
+        BranchRegisterRequestProto result = BranchRegisterRequestProto.newBuilder()
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setApplicationData(applicationData==null?"":applicationData)
+            .setBranchType(BranchTypeProto.valueOf(branchRegisterRequest.getBranchType().name()))
+            .setLockKey(branchRegisterRequest.getLockKey())
+            .setResourceId(resourceId == null ? "" : resourceId)
+            .setXid(branchRegisterRequest.getXid())
+            .build();
+        return result;
+    }
+
+    @Override
+    public BranchRegisterRequest convert2Model(BranchRegisterRequestProto branchRegisterRequestProto) {
+        BranchRegisterRequest branchRegisterRequest = new BranchRegisterRequest();
+        branchRegisterRequest.setApplicationData(branchRegisterRequestProto.getApplicationData());
+        branchRegisterRequest.setBranchType(BranchType.valueOf(branchRegisterRequestProto.getBranchType().name()));
+        branchRegisterRequest.setLockKey(branchRegisterRequestProto.getLockKey());
+        branchRegisterRequest.setResourceId(branchRegisterRequestProto.getResourceId());
+        branchRegisterRequest.setXid(branchRegisterRequestProto.getXid());
+        return branchRegisterRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca6010ea4f2c8b1ad16b69671d52c8af23fe2137
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertor.java
@@ -0,0 +1,74 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.BranchRegisterResponseProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRegisterResponseConvertor
+    implements PbConvertor<BranchRegisterResponse, BranchRegisterResponseProto> {
+    @Override
+    public BranchRegisterResponseProto convert2Proto(BranchRegisterResponse branchRegisterResponse) {
+        final short typeCode = branchRegisterResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = branchRegisterResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(branchRegisterResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(branchRegisterResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        BranchRegisterResponseProto result = BranchRegisterResponseProto.newBuilder().setAbstractTransactionResponse(
+            abstractTransactionResponseProto)
+            .setBranchId(branchRegisterResponse.getBranchId()).build();
+
+        return result;
+    }
+
+    @Override
+    public BranchRegisterResponse convert2Model(BranchRegisterResponseProto branchRegisterResponseProto) {
+        BranchRegisterResponse branchRegisterResponse = new BranchRegisterResponse();
+        branchRegisterResponse.setBranchId(branchRegisterResponseProto.getBranchId());
+        final AbstractResultMessageProto abstractResultMessage = branchRegisterResponseProto
+            .getAbstractTransactionResponse().getAbstractResultMessage();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getMsg());
+        branchRegisterResponse.setResultCode(ResultCode.valueOf(abstractResultMessage.getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            branchRegisterResponseProto.getAbstractTransactionResponse().getTransactionExceptionCode().name()));
+
+        return branchRegisterResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..2db229b111129d8ac38658a953eaf7d3d06ae162
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertor.java
@@ -0,0 +1,71 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.BranchReportRequestProto;
+import io.seata.codec.protobuf.generated.BranchStatusProto;
+import io.seata.codec.protobuf.generated.BranchTypeProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchReportRequestConvertor implements PbConvertor<BranchReportRequest, BranchReportRequestProto> {
+    @Override
+    public BranchReportRequestProto convert2Proto(BranchReportRequest branchReportRequest) {
+        final short typeCode = branchReportRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String applicationData = branchReportRequest.getApplicationData();
+        final String resourceId = branchReportRequest.getResourceId();
+        BranchReportRequestProto result = BranchReportRequestProto.newBuilder().setAbstractTransactionRequest(
+            abstractTransactionRequestProto)
+            .setXid(branchReportRequest.getXid())
+            .setBranchId(branchReportRequest.getBranchId())
+            .setBranchType(BranchTypeProto.valueOf(branchReportRequest.getBranchType().name()))
+            .setApplicationData(applicationData == null ? "" : applicationData)
+            .setResourceId(resourceId == null ? "" : resourceId)
+            .setStatus(BranchStatusProto.valueOf(branchReportRequest.getStatus().name()))
+            .build();
+
+        return result;
+    }
+
+    @Override
+    public BranchReportRequest convert2Model(BranchReportRequestProto branchReportRequestProto) {
+        BranchReportRequest branchReportRequest = new BranchReportRequest();
+        branchReportRequest.setApplicationData(
+            branchReportRequestProto.getApplicationData());
+        branchReportRequest.setBranchId(branchReportRequestProto.getBranchId());
+        branchReportRequest.setResourceId(branchReportRequestProto.getResourceId());
+        branchReportRequest.setXid(branchReportRequestProto.getXid());
+        branchReportRequest.setBranchType(
+            BranchType.valueOf(branchReportRequestProto.getBranchType().name()));
+        branchReportRequest.setStatus(BranchStatus.valueOf(branchReportRequestProto.getStatus().name()));
+        return branchReportRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..6161526748f8a385b930324ef9876fa07c99aa7d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertor.java
@@ -0,0 +1,71 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.BranchReportResponseProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.BranchReportResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchReportResponseConvertor implements PbConvertor<BranchReportResponse, BranchReportResponseProto> {
+    @Override
+    public BranchReportResponseProto convert2Proto(BranchReportResponse branchReportResponse) {
+        final short typeCode = branchReportResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = branchReportResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(branchReportResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(branchReportResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        BranchReportResponseProto result = BranchReportResponseProto.newBuilder()
+            .setAbstractTransactionResponse(abstractTransactionResponseProto).build();
+
+        return result;
+    }
+
+    @Override
+    public BranchReportResponse convert2Model(BranchReportResponseProto branchReportResponseProto) {
+        BranchReportResponse branchRegisterResponse = new BranchReportResponse();
+        final AbstractResultMessageProto abstractResultMessage = branchReportResponseProto
+            .getAbstractTransactionResponse().getAbstractResultMessage();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getMsg());
+        branchRegisterResponse.setResultCode(ResultCode.valueOf(abstractResultMessage.getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            branchReportResponseProto.getAbstractTransactionResponse().getTransactionExceptionCode().name()));
+
+        return branchRegisterResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..99150e18ed9dea829d62d57fbc6aa7eae4609c8f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertor.java
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.BranchRollbackRequestProto;
+import io.seata.codec.protobuf.generated.BranchTypeProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRollbackRequestConvertor implements PbConvertor<BranchRollbackRequest, BranchRollbackRequestProto> {
+    @Override
+    public BranchRollbackRequestProto convert2Proto(BranchRollbackRequest branchRollbackRequest) {
+        final short typeCode = branchRollbackRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String applicationData = branchRollbackRequest.getApplicationData();
+        final String resourceId = branchRollbackRequest.getResourceId();
+        final AbstractBranchEndRequestProto abstractBranchEndRequestProto = AbstractBranchEndRequestProto
+            .newBuilder().
+                setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setXid(branchRollbackRequest.getXid())
+            .setBranchId(branchRollbackRequest.getBranchId())
+            .setBranchType(BranchTypeProto.valueOf(branchRollbackRequest.getBranchType().name()))
+            .setApplicationData(applicationData==null?"":applicationData)
+            .setResourceId(resourceId == null ? "" : resourceId)
+            .build();
+
+        BranchRollbackRequestProto result = BranchRollbackRequestProto.newBuilder().setAbstractBranchEndRequest(
+            abstractBranchEndRequestProto).build();
+
+        return result;
+    }
+
+    @Override
+    public BranchRollbackRequest convert2Model(BranchRollbackRequestProto branchRollbackRequestProto) {
+        BranchRollbackRequest branchCommitRequest = new BranchRollbackRequest();
+        branchCommitRequest.setApplicationData(
+            branchRollbackRequestProto.getAbstractBranchEndRequest().getApplicationData());
+        branchCommitRequest.setBranchId(branchRollbackRequestProto.getAbstractBranchEndRequest().getBranchId());
+        branchCommitRequest.setResourceId(branchRollbackRequestProto.getAbstractBranchEndRequest().getResourceId());
+        branchCommitRequest.setXid(branchRollbackRequestProto.getAbstractBranchEndRequest().getXid());
+        branchCommitRequest.setBranchType(
+            BranchType.valueOf(branchRollbackRequestProto.getAbstractBranchEndRequest().getBranchType().name()));
+
+        return branchCommitRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..b437e5cc6989aaecd7a6a8153c0c25aa67898a37
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertor.java
@@ -0,0 +1,90 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.BranchRollbackResponseProto;
+import io.seata.codec.protobuf.generated.BranchStatusProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRollbackResponseConvertor
+    implements PbConvertor<BranchRollbackResponse, BranchRollbackResponseProto> {
+    @Override
+    public BranchRollbackResponseProto convert2Proto(BranchRollbackResponse branchRollbackResponse) {
+        final short typeCode = branchRollbackResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = branchRollbackResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(branchRollbackResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        final AbstractTransactionResponseProto abstractTransactionRequestProto = AbstractTransactionResponseProto
+            .newBuilder()
+            .setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(branchRollbackResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        final AbstractBranchEndResponseProto abstractBranchEndResponse = AbstractBranchEndResponseProto
+            .newBuilder().
+                setAbstractTransactionResponse(abstractTransactionRequestProto)
+            .setXid(branchRollbackResponse.getXid())
+            .setBranchId(branchRollbackResponse.getBranchId())
+            .setBranchStatus(BranchStatusProto.forNumber(branchRollbackResponse.getBranchStatus().getCode()))
+            .build();
+
+        BranchRollbackResponseProto result = BranchRollbackResponseProto.newBuilder().setAbstractBranchEndResponse(
+            abstractBranchEndResponse).build();
+
+        return result;
+    }
+
+    @Override
+    public BranchRollbackResponse convert2Model(BranchRollbackResponseProto branchRollbackResponseProto) {
+        BranchRollbackResponse branchCommitResponse = new BranchRollbackResponse();
+        branchCommitResponse.setBranchId(branchRollbackResponseProto.getAbstractBranchEndResponse().getBranchId());
+        branchCommitResponse.setBranchStatus(
+            BranchStatus.get(branchRollbackResponseProto.getAbstractBranchEndResponse().getBranchStatusValue()));
+        branchCommitResponse.setXid(branchRollbackResponseProto.getAbstractBranchEndResponse().getXid());
+        branchCommitResponse.setMsg(
+            branchRollbackResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getAbstractResultMessage().getMsg());
+        branchCommitResponse.setResultCode(ResultCode.valueOf(
+            branchRollbackResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getAbstractResultMessage().getResultCode().name()));
+
+        branchCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            branchRollbackResponseProto.getAbstractBranchEndResponse().getAbstractTransactionResponse()
+                .getTransactionExceptionCode().name()));
+        return branchCommitResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c4ae1b3306d558fd014051eb8388c3710aec1b93
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertor.java
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.GlobalBeginRequestProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalBeginRequestConvertor implements PbConvertor<GlobalBeginRequest, GlobalBeginRequestProto> {
+
+    @Override
+    public GlobalBeginRequestProto convert2Proto(GlobalBeginRequest globalBeginRequest) {
+        final short typeCode = globalBeginRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        GlobalBeginRequestProto result = GlobalBeginRequestProto.newBuilder()
+            .setTimeout(globalBeginRequest.getTimeout())
+            .setTransactionName(globalBeginRequest.getTransactionName())
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .build();
+        return result;
+    }
+
+    @Override
+    public GlobalBeginRequest convert2Model(GlobalBeginRequestProto globalBeginRequestProto) {
+        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+        globalBeginRequest.setTimeout(globalBeginRequestProto.getTimeout());
+        globalBeginRequest.setTransactionName(globalBeginRequestProto.getTransactionName());
+        return globalBeginRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..82ae72d9fdabe5fe764b0fe61914c8e8aeb3b9eb
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertor.java
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.GlobalBeginResponseProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalBeginResponseConvertor implements PbConvertor<GlobalBeginResponse, GlobalBeginResponseProto> {
+    @Override
+    public GlobalBeginResponseProto convert2Proto(GlobalBeginResponse globalBeginResponse) {
+        final short typeCode = globalBeginResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = globalBeginResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(globalBeginResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        final AbstractTransactionResponseProto abstractTransactionRequestProto = AbstractTransactionResponseProto
+            .newBuilder()
+            .setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(globalBeginResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        final String extraData = globalBeginResponse.getExtraData();
+        GlobalBeginResponseProto result = GlobalBeginResponseProto.newBuilder().setAbstractTransactionResponse(
+            abstractTransactionRequestProto)
+            .setExtraData(extraData == null ? "" : extraData)
+            .setXid(globalBeginResponse.getXid()).build();
+        return result;
+    }
+
+    @Override
+    public GlobalBeginResponse convert2Model(GlobalBeginResponseProto globalBeginResponseProto) {
+        GlobalBeginResponse branchCommitResponse = new GlobalBeginResponse();
+        branchCommitResponse.setXid(globalBeginResponseProto.getXid());
+        branchCommitResponse.setExtraData(
+            globalBeginResponseProto.getExtraData());
+        branchCommitResponse.setMsg(
+            globalBeginResponseProto.getAbstractTransactionResponse()
+                .getAbstractResultMessage().getMsg());
+        branchCommitResponse.setResultCode(ResultCode.valueOf(
+            globalBeginResponseProto.getAbstractTransactionResponse()
+                .getAbstractResultMessage().getResultCode().name()));
+
+        branchCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            globalBeginResponseProto.getAbstractTransactionResponse()
+                .getTransactionExceptionCode().name()));
+        return branchCommitResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..1fd606c2110129c9485224040244eeb59fe1dfc2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertor.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.GlobalCommitRequestProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalCommitRequestConvertor implements PbConvertor<GlobalCommitRequest, GlobalCommitRequestProto> {
+    @Override
+    public GlobalCommitRequestProto convert2Proto(GlobalCommitRequest globalCommitRequest) {
+        final short typeCode = globalCommitRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String extraData = globalCommitRequest.getExtraData();
+        AbstractGlobalEndRequestProto abstractGlobalEndRequestProto = AbstractGlobalEndRequestProto.newBuilder()
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setXid(globalCommitRequest.getXid())
+            .setExtraData(extraData == null ? "" : extraData)
+            .build();
+
+        GlobalCommitRequestProto result = GlobalCommitRequestProto.newBuilder().setAbstractGlobalEndRequest(
+            abstractGlobalEndRequestProto).build();
+
+        return result;
+
+    }
+
+    @Override
+    public GlobalCommitRequest convert2Model(GlobalCommitRequestProto globalCommitRequestProto) {
+        GlobalCommitRequest branchCommitRequest = new GlobalCommitRequest();
+        branchCommitRequest.setExtraData(globalCommitRequestProto.getAbstractGlobalEndRequest().getExtraData());
+        branchCommitRequest.setXid(globalCommitRequestProto.getAbstractGlobalEndRequest().getXid());
+        return branchCommitRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c70db73e94bfc54a511941c0740b422fc02fe9b7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertor.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.GlobalCommitResponseProto;
+import io.seata.codec.protobuf.generated.GlobalStatusProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalCommitResponseConvertor implements PbConvertor<GlobalCommitResponse, GlobalCommitResponseProto> {
+    @Override
+    public GlobalCommitResponseProto convert2Proto(GlobalCommitResponse globalCommitResponse) {
+        final short typeCode = globalCommitResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = globalCommitResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(globalCommitResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(globalCommitResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        AbstractGlobalEndResponseProto abstractGlobalEndResponseProto = AbstractGlobalEndResponseProto.newBuilder()
+            .setAbstractTransactionResponse(abstractTransactionResponseProto)
+            .setGlobalStatus(GlobalStatusProto.valueOf(globalCommitResponse.getGlobalStatus().name()))
+            .build();
+
+        GlobalCommitResponseProto result = GlobalCommitResponseProto.newBuilder().setAbstractGlobalEndResponse(
+            abstractGlobalEndResponseProto).build();
+
+        return result;
+    }
+
+    @Override
+    public GlobalCommitResponse convert2Model(GlobalCommitResponseProto globalCommitResponseProto) {
+        GlobalCommitResponse branchRegisterResponse = new GlobalCommitResponse();
+        final AbstractGlobalEndResponseProto abstractGlobalEndResponse = globalCommitResponseProto
+            .getAbstractGlobalEndResponse();
+        AbstractTransactionResponseProto abstractResultMessage = abstractGlobalEndResponse
+            .getAbstractTransactionResponse();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getAbstractResultMessage().getMsg());
+        branchRegisterResponse.setResultCode(
+            ResultCode.valueOf(abstractResultMessage.getAbstractResultMessage().getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            abstractResultMessage.getTransactionExceptionCode().name()));
+        branchRegisterResponse.setGlobalStatus(
+            GlobalStatus.valueOf(abstractGlobalEndResponse.getGlobalStatus().name()));
+
+        return branchRegisterResponse;
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3c902639e8d0727e249311a2bf0639c94538106
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertor.java
@@ -0,0 +1,70 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.BranchRegisterRequestProto;
+import io.seata.codec.protobuf.generated.BranchTypeProto;
+import io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalLockQueryRequestConvertor
+    implements PbConvertor<GlobalLockQueryRequest, GlobalLockQueryRequestProto> {
+    @Override
+    public GlobalLockQueryRequestProto convert2Proto(GlobalLockQueryRequest globalLockQueryRequest) {
+        final short typeCode = globalLockQueryRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String applicationData = globalLockQueryRequest.getApplicationData();
+        BranchRegisterRequestProto branchRegisterRequestProto = BranchRegisterRequestProto.newBuilder()
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setApplicationData(applicationData==null?"":applicationData)
+            .setBranchType(BranchTypeProto.valueOf(globalLockQueryRequest.getBranchType().name()))
+            .setLockKey(globalLockQueryRequest.getLockKey())
+            .setResourceId(globalLockQueryRequest.getResourceId())
+            .setXid(globalLockQueryRequest.getXid())
+            .build();
+
+        GlobalLockQueryRequestProto result = GlobalLockQueryRequestProto.newBuilder().setBranchRegisterRequest(
+            branchRegisterRequestProto).build();
+
+        return result;
+    }
+
+    @Override
+    public GlobalLockQueryRequest convert2Model(GlobalLockQueryRequestProto globalLockQueryRequestProto) {
+        GlobalLockQueryRequest branchRegisterRequest = new GlobalLockQueryRequest();
+        BranchRegisterRequestProto branchRegisterRequestProto = globalLockQueryRequestProto.getBranchRegisterRequest();
+        branchRegisterRequest.setApplicationData(branchRegisterRequestProto.getApplicationData());
+        branchRegisterRequest.setBranchType(BranchType.valueOf(branchRegisterRequestProto.getBranchType().name()));
+        branchRegisterRequest.setLockKey(branchRegisterRequestProto.getLockKey());
+        branchRegisterRequest.setResourceId(branchRegisterRequestProto.getResourceId());
+        branchRegisterRequest.setXid(branchRegisterRequestProto.getXid());
+        return branchRegisterRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7b7967135880cb13c62003c0a504b730b2f0ed1b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertor.java
@@ -0,0 +1,75 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalLockQueryResponseConvertor
+    implements PbConvertor<GlobalLockQueryResponse, GlobalLockQueryResponseProto> {
+    @Override
+    public GlobalLockQueryResponseProto convert2Proto(GlobalLockQueryResponse globalLockQueryResponse) {
+        final short typeCode = globalLockQueryResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = globalLockQueryResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(globalLockQueryResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(globalLockQueryResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        GlobalLockQueryResponseProto result = GlobalLockQueryResponseProto.newBuilder().setLockable(
+            globalLockQueryResponse.isLockable())
+            .setAbstractTransactionResponse(abstractTransactionResponseProto).build();
+
+        return result;
+    }
+
+    @Override
+    public GlobalLockQueryResponse convert2Model(GlobalLockQueryResponseProto globalLockQueryResponseProto) {
+
+        GlobalLockQueryResponse branchRegisterResponse = new GlobalLockQueryResponse();
+        AbstractTransactionResponseProto branchRegisterResponseProto = globalLockQueryResponseProto
+            .getAbstractTransactionResponse();
+        final AbstractResultMessageProto abstractResultMessage = branchRegisterResponseProto.getAbstractResultMessage();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getMsg());
+        branchRegisterResponse.setResultCode(ResultCode.valueOf(abstractResultMessage.getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            branchRegisterResponseProto.getTransactionExceptionCode().name()));
+        branchRegisterResponse.setLockable(globalLockQueryResponseProto.getLockable());
+        return branchRegisterResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..a804422e05b0404ee8942206cd8af01b3046de9d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertor.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.GlobalRollbackRequestProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalRollbackRequestConvertor implements PbConvertor<GlobalRollbackRequest, GlobalRollbackRequestProto> {
+    @Override
+    public GlobalRollbackRequestProto convert2Proto(GlobalRollbackRequest globalRollbackRequest) {
+        final short typeCode = globalRollbackRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String extraData = globalRollbackRequest.getExtraData();
+        AbstractGlobalEndRequestProto abstractGlobalEndRequestProto = AbstractGlobalEndRequestProto.newBuilder()
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setXid(globalRollbackRequest.getXid())
+            .setExtraData(extraData==null?"":extraData)
+            .build();
+
+        GlobalRollbackRequestProto result = GlobalRollbackRequestProto.newBuilder().setAbstractGlobalEndRequest(
+            abstractGlobalEndRequestProto).build();
+
+        return result;
+    }
+
+    @Override
+    public GlobalRollbackRequest convert2Model(GlobalRollbackRequestProto globalRollbackRequestProto) {
+        GlobalRollbackRequest branchCommitRequest = new GlobalRollbackRequest();
+        branchCommitRequest.setExtraData(globalRollbackRequestProto.getAbstractGlobalEndRequest().getExtraData());
+        branchCommitRequest.setXid(globalRollbackRequestProto.getAbstractGlobalEndRequest().getXid());
+        return branchCommitRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..516e8e08423ff6d19a31c343d73453d9e0c9cb68
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertor.java
@@ -0,0 +1,87 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.GlobalRollbackResponseProto;
+import io.seata.codec.protobuf.generated.GlobalStatusProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalRollbackResponseConvertor
+    implements PbConvertor<GlobalRollbackResponse, GlobalRollbackResponseProto> {
+    @Override
+    public GlobalRollbackResponseProto convert2Proto(GlobalRollbackResponse globalRollbackResponse) {
+        final short typeCode = globalRollbackResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = globalRollbackResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(globalRollbackResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(globalRollbackResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        AbstractGlobalEndResponseProto abstractGlobalEndResponseProto = AbstractGlobalEndResponseProto.newBuilder()
+            .setAbstractTransactionResponse(abstractTransactionResponseProto)
+            .setGlobalStatus(GlobalStatusProto.valueOf(globalRollbackResponse.getGlobalStatus().name()))
+            .build();
+
+        GlobalRollbackResponseProto result = GlobalRollbackResponseProto.newBuilder().setAbstractGlobalEndResponse(
+            abstractGlobalEndResponseProto).build();
+
+        return result;
+
+    }
+
+    @Override
+    public GlobalRollbackResponse convert2Model(GlobalRollbackResponseProto globalRollbackResponseProto) {
+        GlobalRollbackResponse branchRegisterResponse = new GlobalRollbackResponse();
+        final AbstractGlobalEndResponseProto abstractGlobalEndResponse = globalRollbackResponseProto
+            .getAbstractGlobalEndResponse();
+        AbstractTransactionResponseProto abstractResultMessage = abstractGlobalEndResponse
+            .getAbstractTransactionResponse();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getAbstractResultMessage().getMsg());
+        branchRegisterResponse.setResultCode(
+            ResultCode.valueOf(abstractResultMessage.getAbstractResultMessage().getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            abstractResultMessage.getTransactionExceptionCode().name()));
+        branchRegisterResponse.setGlobalStatus(
+            GlobalStatus.valueOf(abstractGlobalEndResponse.getGlobalStatus().name()));
+
+        return branchRegisterResponse;
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..68a17e2d9e6123d74355a0e58c8aa3d278c6976a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertor.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionRequestProto;
+import io.seata.codec.protobuf.generated.GlobalStatusRequestProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalStatusRequestConvertor implements PbConvertor<GlobalStatusRequest, GlobalStatusRequestProto> {
+    @Override
+    public GlobalStatusRequestProto convert2Proto(GlobalStatusRequest globalStatusRequest) {
+        final short typeCode = globalStatusRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final AbstractTransactionRequestProto abstractTransactionRequestProto = AbstractTransactionRequestProto
+            .newBuilder().setAbstractMessage(
+                abstractMessage).build();
+
+        final String extraData = globalStatusRequest.getExtraData();
+        AbstractGlobalEndRequestProto abstractGlobalEndRequestProto = AbstractGlobalEndRequestProto.newBuilder()
+            .setAbstractTransactionRequest(abstractTransactionRequestProto)
+            .setXid(globalStatusRequest.getXid())
+            .setExtraData(extraData==null?"":extraData)
+            .build();
+
+        GlobalStatusRequestProto result = GlobalStatusRequestProto.newBuilder().setAbstractGlobalEndRequest(
+            abstractGlobalEndRequestProto).build();
+
+        return result;
+    }
+
+    @Override
+    public GlobalStatusRequest convert2Model(GlobalStatusRequestProto globalStatusRequestProto) {
+        GlobalStatusRequest branchCommitRequest = new GlobalStatusRequest();
+        branchCommitRequest.setExtraData(globalStatusRequestProto.getAbstractGlobalEndRequest().getExtraData());
+        branchCommitRequest.setXid(globalStatusRequestProto.getAbstractGlobalEndRequest().getXid());
+        return branchCommitRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..3fb4f2e81a1e1c284c0c0464cc8b9f62211c47cf
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertor.java
@@ -0,0 +1,84 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.AbstractTransactionResponseProto;
+import io.seata.codec.protobuf.generated.GlobalStatusProto;
+import io.seata.codec.protobuf.generated.GlobalStatusResponseProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.codec.protobuf.generated.TransactionExceptionCodeProto;
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalStatusResponseConvertor implements PbConvertor<GlobalStatusResponse, GlobalStatusResponseProto> {
+    @Override
+    public GlobalStatusResponseProto convert2Proto(GlobalStatusResponse globalStatusResponse) {
+        final short typeCode = globalStatusResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = globalStatusResponse.getMsg();
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(globalStatusResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        AbstractTransactionResponseProto abstractTransactionResponseProto = AbstractTransactionResponseProto
+            .newBuilder().setAbstractResultMessage(abstractResultMessageProto)
+            .setTransactionExceptionCode(
+                TransactionExceptionCodeProto.valueOf(globalStatusResponse.getTransactionExceptionCode().name()))
+            .build();
+
+        AbstractGlobalEndResponseProto abstractGlobalEndResponseProto = AbstractGlobalEndResponseProto.newBuilder()
+            .setAbstractTransactionResponse(abstractTransactionResponseProto)
+            .setGlobalStatus(GlobalStatusProto.valueOf(globalStatusResponse.getGlobalStatus().name()))
+            .build();
+
+        GlobalStatusResponseProto result = GlobalStatusResponseProto.newBuilder().setAbstractGlobalEndResponse(
+            abstractGlobalEndResponseProto).build();
+        return result;
+    }
+
+    @Override
+    public GlobalStatusResponse convert2Model(GlobalStatusResponseProto globalStatusResponseProto) {
+        GlobalStatusResponse branchRegisterResponse = new GlobalStatusResponse();
+        final AbstractGlobalEndResponseProto abstractGlobalEndResponse = globalStatusResponseProto
+            .getAbstractGlobalEndResponse();
+        AbstractTransactionResponseProto abstractResultMessage = abstractGlobalEndResponse
+            .getAbstractTransactionResponse();
+        branchRegisterResponse.setMsg(
+            abstractResultMessage.getAbstractResultMessage().getMsg());
+        branchRegisterResponse.setResultCode(
+            ResultCode.valueOf(abstractResultMessage.getAbstractResultMessage().getResultCode().name()));
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.valueOf(
+            abstractResultMessage.getTransactionExceptionCode().name()));
+        branchRegisterResponse.setGlobalStatus(
+            GlobalStatus.valueOf(abstractGlobalEndResponse.getGlobalStatus().name()));
+
+        return branchRegisterResponse;
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..33e5c1d62c0e8aa450b4c0c916f64cdca3e09fe6
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertor.java
@@ -0,0 +1,36 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.HeartbeatMessageProto;
+import io.seata.core.protocol.HeartbeatMessage;
+
+/**
+ * @author leizhiyuan
+ */
+public class HeartbeatMessageConvertor implements PbConvertor<HeartbeatMessage, HeartbeatMessageProto> {
+    @Override
+    public HeartbeatMessageProto convert2Proto(HeartbeatMessage heartbeatMessage) {
+        HeartbeatMessageProto result = HeartbeatMessageProto.newBuilder().setPing(heartbeatMessage.isPing())
+            .build();
+        return result;
+    }
+
+    @Override
+    public HeartbeatMessage convert2Model(HeartbeatMessageProto heartbeatMessageProto) {
+        return heartbeatMessageProto.getPing() ? HeartbeatMessage.PING : HeartbeatMessage.PONG;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e59b5933ebf5e254e1689f9113800ea061eaf3e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertor.java
@@ -0,0 +1,90 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.protobuf.Any;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+import io.seata.common.exception.ShouldNeverHappenException;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.MergeResultMessage;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.MergedResultMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.manager.ProtobufConvertManager;
+
+/**
+ * @author leizhiyuan
+ */
+public class MergeResultMessageConvertor implements PbConvertor<MergeResultMessage, MergedResultMessageProto> {
+    @Override
+    public MergedResultMessageProto convert2Proto(MergeResultMessage mergeResultMessage) {
+        final short typeCode = mergeResultMessage.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        List<Any> lists = new ArrayList<>();
+        for (AbstractMessage msg : mergeResultMessage.msgs) {
+            final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchConvertor(
+                msg.getClass().getName());
+            lists.add(Any.pack((Message)pbConvertor.convert2Proto(msg)));
+        }
+
+        MergedResultMessageProto mergedWarpMessageProto = MergedResultMessageProto.newBuilder().setAbstractMessage(
+            abstractMessage)
+            .addAllMsgs(lists)
+            .build();
+
+        return mergedWarpMessageProto;
+    }
+
+    @Override
+    public MergeResultMessage convert2Model(MergedResultMessageProto mergedResultMessageProto) {
+        MergeResultMessage result = new MergeResultMessage();
+        List<Any> anys = mergedResultMessageProto.getMsgsList();
+
+        List<AbstractResultMessage> temp = new ArrayList<>();
+        for (Any any : anys) {
+            final Class clazz = ProtobufConvertManager.getInstance().fetchProtoClass(
+                getTypeNameFromTypeUrl(any.getTypeUrl()));
+            if (any.is(clazz)) {
+                try {
+                    Object ob = any.unpack(clazz);
+                    final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchReversedConvertor(
+                        clazz.getName());
+                    Object model = pbConvertor.convert2Model(ob);
+                    temp.add((AbstractResultMessage)model);
+                } catch (InvalidProtocolBufferException e) {
+                    throw new ShouldNeverHappenException(e);
+                }
+            }
+        }
+        result.setMsgs(temp.toArray(new AbstractResultMessage[temp.size()]));
+
+        return result;
+    }
+
+    private static String getTypeNameFromTypeUrl(
+        java.lang.String typeUrl) {
+        int pos = typeUrl.lastIndexOf('/');
+        return pos == -1 ? "" : typeUrl.substring(pos + 1);
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergedWarpMessageConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergedWarpMessageConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..92b68e906aa1999727cb0198eb8cef3f3bb1ed37
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/MergedWarpMessageConvertor.java
@@ -0,0 +1,91 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.protobuf.Any;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Message;
+import io.seata.common.exception.ShouldNeverHappenException;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.MergedWarpMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.manager.ProtobufConvertManager;
+
+/**
+ * @author leizhiyuan
+ */
+public class MergedWarpMessageConvertor implements PbConvertor<MergedWarpMessage, MergedWarpMessageProto> {
+
+    @Override
+    public MergedWarpMessageProto convert2Proto(MergedWarpMessage mergedWarpMessage) {
+
+        final short typeCode = mergedWarpMessage.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        List<Any> lists = new ArrayList<>();
+        for (AbstractMessage msg : mergedWarpMessage.msgs) {
+            final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchConvertor(
+                msg.getClass().getName());
+            lists.add(Any.pack((Message)pbConvertor.convert2Proto(msg)));
+        }
+
+        MergedWarpMessageProto mergedWarpMessageProto = MergedWarpMessageProto.newBuilder().setAbstractMessage(
+            abstractMessage)
+            .addAllMsgs(lists)
+            .addAllMsgIds(mergedWarpMessage.msgIds)
+            .build();
+
+        return mergedWarpMessageProto;
+
+    }
+
+    @Override
+    public MergedWarpMessage convert2Model(MergedWarpMessageProto mergedWarpMessageProto) {
+        MergedWarpMessage result = new MergedWarpMessage();
+        List<Any> anys = mergedWarpMessageProto.getMsgsList();
+        for (Any any : anys) {
+            final Class clazz = ProtobufConvertManager.getInstance().fetchProtoClass(
+                getTypeNameFromTypeUrl(any.getTypeUrl()));
+            if (any.is(clazz)) {
+                try {
+                    Object ob = any.unpack(clazz);
+                    final PbConvertor pbConvertor = ProtobufConvertManager.getInstance().fetchReversedConvertor(
+                        clazz.getName());
+                    Object model = pbConvertor.convert2Model(ob);
+                    result.msgs.add((AbstractMessage)model);
+                } catch (InvalidProtocolBufferException e) {
+                    throw new ShouldNeverHappenException(e);
+                }
+            }
+        }
+        result.msgIds = mergedWarpMessageProto.getMsgIdsList();
+
+        return result;
+    }
+
+    private static String getTypeNameFromTypeUrl(
+        java.lang.String typeUrl) {
+        int pos = typeUrl.lastIndexOf('/');
+        return pos == -1 ? "" : typeUrl.substring(pos + 1);
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/PbConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/PbConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd0bc73989ad5869e5141bba14052aa9bc2f896f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/PbConvertor.java
@@ -0,0 +1,26 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+/**
+ * @author leizhiyuan
+ */
+public interface PbConvertor<T, S> {
+
+    public S convert2Proto(T t);
+
+    public T convert2Model(S s);
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ca246c24cef763b81b740be1a2826de71baa7e5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertor.java
@@ -0,0 +1,64 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.RegisterRMRequestProto;
+import io.seata.core.protocol.RegisterRMRequest;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterRMRequestConvertor implements PbConvertor<RegisterRMRequest, RegisterRMRequestProto> {
+    @Override
+    public RegisterRMRequestProto convert2Proto(RegisterRMRequest registerRMRequest) {
+        final short typeCode = registerRMRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String extraData = registerRMRequest.getExtraData();
+        AbstractIdentifyRequestProto abstractIdentifyRequestProto = AbstractIdentifyRequestProto.newBuilder()
+            .setAbstractMessage(abstractMessage)
+            .setApplicationId(registerRMRequest.getApplicationId())
+            .setExtraData(extraData == null ? "" : extraData)
+            .setTransactionServiceGroup(registerRMRequest.getTransactionServiceGroup())
+            .setVersion(registerRMRequest.getVersion())
+            .build();
+        RegisterRMRequestProto result = RegisterRMRequestProto.newBuilder().setAbstractIdentifyRequest(
+            abstractIdentifyRequestProto)
+            .setResourceIds(registerRMRequest.getResourceIds() == null ? "" : registerRMRequest.getResourceIds())
+            .build();
+
+        return result;
+    }
+
+    @Override
+    public RegisterRMRequest convert2Model(RegisterRMRequestProto registerRMRequestProto) {
+        RegisterRMRequest registerRMRequest = new RegisterRMRequest();
+
+        AbstractIdentifyRequestProto abstractIdentifyRequest = registerRMRequestProto.getAbstractIdentifyRequest();
+        registerRMRequest.setResourceIds(registerRMRequestProto.getResourceIds());
+        registerRMRequest.setApplicationId(abstractIdentifyRequest.getApplicationId());
+        registerRMRequest.setExtraData(abstractIdentifyRequest.getExtraData());
+        registerRMRequest.setTransactionServiceGroup(abstractIdentifyRequest.getTransactionServiceGroup());
+        registerRMRequest.setVersion(abstractIdentifyRequest.getVersion());
+
+        return registerRMRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..d470713e6c62bf311408261e461d91ce770a61bd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertor.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.RegisterRMResponseProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.core.protocol.RegisterRMResponse;
+import io.seata.core.protocol.ResultCode;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterRMResponseConvertor implements PbConvertor<RegisterRMResponse, RegisterRMResponseProto> {
+    @Override
+    public RegisterRMResponseProto convert2Proto(RegisterRMResponse registerRMResponse) {
+        final short typeCode = registerRMResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = registerRMResponse.getMsg();
+
+        //for code
+        if (registerRMResponse.getResultCode() == null) {
+            if (registerRMResponse.isIdentified()) {
+                registerRMResponse.setResultCode(ResultCode.Success);
+            } else {
+                registerRMResponse.setResultCode(ResultCode.Failed);
+
+            }
+        }
+
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(registerRMResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        final String extraData = registerRMResponse.getExtraData();
+        AbstractIdentifyResponseProto abstractIdentifyResponseProto = AbstractIdentifyResponseProto.newBuilder()
+            .setAbstractResultMessage(abstractResultMessageProto)
+            .setExtraData(extraData==null?"":extraData)
+            .setVersion(registerRMResponse.getVersion())
+            .setIdentified(registerRMResponse.isIdentified())
+            .build();
+
+        RegisterRMResponseProto result = RegisterRMResponseProto.newBuilder()
+            .setAbstractIdentifyResponse(abstractIdentifyResponseProto).build();
+
+        return result;
+    }
+
+    @Override
+    public RegisterRMResponse convert2Model(RegisterRMResponseProto registerRMResponseProto) {
+        RegisterRMResponse registerRMRequest = new RegisterRMResponse();
+
+        AbstractIdentifyResponseProto abstractIdentifyRequestProto = registerRMResponseProto
+            .getAbstractIdentifyResponse();
+        registerRMRequest.setExtraData(abstractIdentifyRequestProto.getExtraData());
+        registerRMRequest.setVersion(abstractIdentifyRequestProto.getVersion());
+        registerRMRequest.setIdentified(abstractIdentifyRequestProto.getIdentified());
+
+        registerRMRequest.setMsg(abstractIdentifyRequestProto.getAbstractResultMessage().getMsg());
+        registerRMRequest.setResultCode(
+            ResultCode.valueOf(abstractIdentifyRequestProto.getAbstractResultMessage().getResultCode().name()));
+
+        return registerRMRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fd1507abfb308b9ce2243f5ef9e5251654a167c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertor.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.RegisterTMRequest;
+import io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.RegisterTMRequestProto;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterTMRequestConvertor implements PbConvertor<RegisterTMRequest, RegisterTMRequestProto> {
+    @Override
+    public RegisterTMRequestProto convert2Proto(RegisterTMRequest registerTMRequest) {
+        final short typeCode = registerTMRequest.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String extraData = registerTMRequest.getExtraData();
+        AbstractIdentifyRequestProto abstractIdentifyRequestProto = AbstractIdentifyRequestProto.newBuilder()
+            .setAbstractMessage(abstractMessage)
+            .setApplicationId(registerTMRequest.getApplicationId())
+            .setExtraData(extraData==null?"":extraData)
+            .setTransactionServiceGroup(registerTMRequest.getTransactionServiceGroup())
+            .setVersion(registerTMRequest.getVersion())
+            .build();
+
+        RegisterTMRequestProto result = RegisterTMRequestProto.newBuilder().setAbstractIdentifyRequest(
+            abstractIdentifyRequestProto).build();
+
+        return result;
+    }
+
+    @Override
+    public RegisterTMRequest convert2Model(RegisterTMRequestProto registerTMRequestProto) {
+        RegisterTMRequest registerRMRequest = new RegisterTMRequest();
+
+        AbstractIdentifyRequestProto abstractIdentifyRequest = registerTMRequestProto.getAbstractIdentifyRequest();
+        registerRMRequest.setApplicationId(abstractIdentifyRequest.getApplicationId());
+        registerRMRequest.setExtraData(abstractIdentifyRequest.getExtraData());
+        registerRMRequest.setTransactionServiceGroup(abstractIdentifyRequest.getTransactionServiceGroup());
+        registerRMRequest.setVersion(abstractIdentifyRequest.getVersion());
+
+        return registerRMRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertor.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertor.java
new file mode 100644
index 0000000000000000000000000000000000000000..a065c9b9da12425fb9ca4881e3c559793aa780c9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertor.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto;
+import io.seata.codec.protobuf.generated.AbstractMessageProto;
+import io.seata.codec.protobuf.generated.AbstractResultMessageProto;
+import io.seata.codec.protobuf.generated.MessageTypeProto;
+import io.seata.codec.protobuf.generated.RegisterTMResponseProto;
+import io.seata.codec.protobuf.generated.ResultCodeProto;
+import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.protocol.ResultCode;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterTMResponseConvertor implements PbConvertor<RegisterTMResponse, RegisterTMResponseProto> {
+    @Override
+    public RegisterTMResponseProto convert2Proto(RegisterTMResponse registerTMResponse) {
+        final short typeCode = registerTMResponse.getTypeCode();
+
+        final AbstractMessageProto abstractMessage = AbstractMessageProto.newBuilder().setMessageType(
+            MessageTypeProto.forNumber(typeCode)).build();
+
+        final String msg = registerTMResponse.getMsg();
+        //for code
+        if (registerTMResponse.getResultCode() == null) {
+            if (registerTMResponse.isIdentified()) {
+                registerTMResponse.setResultCode(ResultCode.Success);
+            } else {
+                registerTMResponse.setResultCode(ResultCode.Failed);
+
+            }
+        }
+
+        final AbstractResultMessageProto abstractResultMessageProto = AbstractResultMessageProto.newBuilder().setMsg(
+            msg == null ? "" : msg)
+            .setResultCode(ResultCodeProto.valueOf(registerTMResponse.getResultCode().name())).setAbstractMessage(
+                abstractMessage).build();
+
+        final String extraData = registerTMResponse.getExtraData();
+        AbstractIdentifyResponseProto abstractIdentifyResponseProto = AbstractIdentifyResponseProto.newBuilder()
+            .setAbstractResultMessage(abstractResultMessageProto)
+            .setExtraData(extraData == null ? "" : extraData)
+            .setVersion(registerTMResponse.getVersion())
+            .setIdentified(registerTMResponse.isIdentified())
+            .build();
+
+        RegisterTMResponseProto result = RegisterTMResponseProto.newBuilder().setAbstractIdentifyResponse(
+            abstractIdentifyResponseProto).build();
+
+        return result;
+    }
+
+    @Override
+    public RegisterTMResponse convert2Model(RegisterTMResponseProto registerTMResponseProto) {
+        RegisterTMResponse registerRMRequest = new RegisterTMResponse();
+
+        AbstractIdentifyResponseProto abstractIdentifyRequestProto = registerTMResponseProto
+            .getAbstractIdentifyResponse();
+        registerRMRequest.setExtraData(abstractIdentifyRequestProto.getExtraData());
+        registerRMRequest.setVersion(abstractIdentifyRequestProto.getVersion());
+        registerRMRequest.setIdentified(abstractIdentifyRequestProto.getIdentified());
+
+        registerRMRequest.setMsg(abstractIdentifyRequestProto.getAbstractResultMessage().getMsg());
+        registerRMRequest.setResultCode(
+            ResultCode.valueOf(abstractIdentifyRequestProto.getAbstractResultMessage().getResultCode().name()));
+
+        return registerRMRequest;
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..81aa3d3a16d035f7799c82734b1f6c253d4def67
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequest.java
@@ -0,0 +1,69 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractBranchEndRequest {
+  private AbstractBranchEndRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\036abstractBranchEndRequest.proto\022\032io.sea" +
+      "ta.protocol.protobuf\032 abstractTransactio" +
+      "nRequest.proto\032\020branchType.proto\"\215\002\n\035Abs" +
+      "tractBranchEndRequestProto\022_\n\032abstractTr" +
+      "ansactionRequest\030\001 \001(\0132;.io.seata.protoc" +
+      "ol.protobuf.AbstractTransactionRequestPr" +
+      "oto\022\013\n\003xid\030\002 \001(\t\022\020\n\010branchId\030\003 \001(\003\022?\n\nbr" +
+      "anchType\030\004 \001(\0162+.io.seata.protocol.proto" +
+      "buf.BranchTypeProto\022\022\n\nresourceId\030\005 \001(\t\022" +
+      "\027\n\017applicationData\030\006 \001(\tB?\n!io.seata.cod" +
+      "ec.protobuf.generatedB\030AbstractBranchEnd" +
+      "RequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor(),
+          io.seata.codec.protobuf.generated.BranchType.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionRequest", "Xid", "BranchId", "BranchType", "ResourceId", "ApplicationData", });
+    io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor();
+    io.seata.codec.protobuf.generated.BranchType.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..4aa2255b424f089690f2c6ed0b16a97124ce8a56
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProto.java
@@ -0,0 +1,1251 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractBranchEndRequestProto}
+ */
+public  final class AbstractBranchEndRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractBranchEndRequestProto)
+    AbstractBranchEndRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractBranchEndRequestProto.newBuilder() to construct.
+  private AbstractBranchEndRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractBranchEndRequestProto() {
+    xid_ = "";
+    branchType_ = 0;
+    resourceId_ = "";
+    applicationData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractBranchEndRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder subBuilder = null;
+            if (abstractTransactionRequest_ != null) {
+              subBuilder = abstractTransactionRequest_.toBuilder();
+            }
+            abstractTransactionRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionRequest_);
+              abstractTransactionRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 24: {
+
+            branchId_ = input.readInt64();
+            break;
+          }
+          case 32: {
+            int rawValue = input.readEnum();
+
+            branchType_ = rawValue;
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            resourceId_ = s;
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            applicationData_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractBranchEndRequest.internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractBranchEndRequest.internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.class, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public boolean hasAbstractTransactionRequest() {
+    return abstractTransactionRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+    return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+    return getAbstractTransactionRequest();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int BRANCHID_FIELD_NUMBER = 3;
+  private long branchId_;
+  /**
+   * <pre>
+   **
+   * The Branch id.
+   * </pre>
+   *
+   * <code>int64 branchId = 3;</code>
+   */
+  public long getBranchId() {
+    return branchId_;
+  }
+
+  public static final int BRANCHTYPE_FIELD_NUMBER = 4;
+  private int branchType_;
+  /**
+   * <pre>
+   **
+   * The Branch type.
+   * </pre>
+   *
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+   */
+  public int getBranchTypeValue() {
+    return branchType_;
+  }
+  /**
+   * <pre>
+   **
+   * The Branch type.
+   * </pre>
+   *
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+    return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+  }
+
+  public static final int RESOURCEID_FIELD_NUMBER = 5;
+  private volatile java.lang.Object resourceId_;
+  /**
+   * <pre>
+   **
+   * The Resource id.
+   * </pre>
+   *
+   * <code>string resourceId = 5;</code>
+   */
+  public java.lang.String getResourceId() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      resourceId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   **
+   * The Resource id.
+   * </pre>
+   *
+   * <code>string resourceId = 5;</code>
+   */
+  public com.google.protobuf.ByteString
+      getResourceIdBytes() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      resourceId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int APPLICATIONDATA_FIELD_NUMBER = 6;
+  private volatile java.lang.Object applicationData_;
+  /**
+   * <pre>
+   **
+   * The Application data.
+   * </pre>
+   *
+   * <code>string applicationData = 6;</code>
+   */
+  public java.lang.String getApplicationData() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      applicationData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <pre>
+   **
+   * The Application data.
+   * </pre>
+   *
+   * <code>string applicationData = 6;</code>
+   */
+  public com.google.protobuf.ByteString
+      getApplicationDataBytes() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      applicationData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionRequest_ != null) {
+      output.writeMessage(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (branchId_ != 0L) {
+      output.writeInt64(3, branchId_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      output.writeEnum(4, branchType_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, resourceId_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, applicationData_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (branchId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, branchId_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(4, branchType_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, resourceId_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, applicationData_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto other = (io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto) obj;
+
+    if (hasAbstractTransactionRequest() != other.hasAbstractTransactionRequest()) return false;
+    if (hasAbstractTransactionRequest()) {
+      if (!getAbstractTransactionRequest()
+          .equals(other.getAbstractTransactionRequest())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (getBranchId()
+        != other.getBranchId()) return false;
+    if (branchType_ != other.branchType_) return false;
+    if (!getResourceId()
+        .equals(other.getResourceId())) return false;
+    if (!getApplicationData()
+        .equals(other.getApplicationData())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionRequest()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionRequest().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + BRANCHID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getBranchId());
+    hash = (37 * hash) + BRANCHTYPE_FIELD_NUMBER;
+    hash = (53 * hash) + branchType_;
+    hash = (37 * hash) + RESOURCEID_FIELD_NUMBER;
+    hash = (53 * hash) + getResourceId().hashCode();
+    hash = (37 * hash) + APPLICATIONDATA_FIELD_NUMBER;
+    hash = (53 * hash) + getApplicationData().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractBranchEndRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractBranchEndRequestProto)
+      io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndRequest.internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndRequest.internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.class, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+      xid_ = "";
+
+      branchId_ = 0L;
+
+      branchType_ = 0;
+
+      resourceId_ = "";
+
+      applicationData_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndRequest.internal_static_io_seata_protocol_protobuf_AbstractBranchEndRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto build() {
+      io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto result = new io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto(this);
+      if (abstractTransactionRequestBuilder_ == null) {
+        result.abstractTransactionRequest_ = abstractTransactionRequest_;
+      } else {
+        result.abstractTransactionRequest_ = abstractTransactionRequestBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.branchId_ = branchId_;
+      result.branchType_ = branchType_;
+      result.resourceId_ = resourceId_;
+      result.applicationData_ = applicationData_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionRequest()) {
+        mergeAbstractTransactionRequest(other.getAbstractTransactionRequest());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (other.getBranchId() != 0L) {
+        setBranchId(other.getBranchId());
+      }
+      if (other.branchType_ != 0) {
+        setBranchTypeValue(other.getBranchTypeValue());
+      }
+      if (!other.getResourceId().isEmpty()) {
+        resourceId_ = other.resourceId_;
+        onChanged();
+      }
+      if (!other.getApplicationData().isEmpty()) {
+        applicationData_ = other.applicationData_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> abstractTransactionRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public boolean hasAbstractTransactionRequest() {
+      return abstractTransactionRequestBuilder_ != null || abstractTransactionRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      } else {
+        return abstractTransactionRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionRequest_ = value;
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder builderForValue) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder mergeAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (abstractTransactionRequest_ != null) {
+          abstractTransactionRequest_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder(abstractTransactionRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder clearAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+        onChanged();
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder getAbstractTransactionRequestBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+      if (abstractTransactionRequestBuilder_ != null) {
+        return abstractTransactionRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> 
+        getAbstractTransactionRequestFieldBuilder() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder>(
+                getAbstractTransactionRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionRequest_ = null;
+      }
+      return abstractTransactionRequestBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private long branchId_ ;
+    /**
+     * <pre>
+     **
+     * The Branch id.
+     * </pre>
+     *
+     * <code>int64 branchId = 3;</code>
+     */
+    public long getBranchId() {
+      return branchId_;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch id.
+     * </pre>
+     *
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder setBranchId(long value) {
+      
+      branchId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch id.
+     * </pre>
+     *
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder clearBranchId() {
+      
+      branchId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private int branchType_ = 0;
+    /**
+     * <pre>
+     **
+     * The Branch type.
+     * </pre>
+     *
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+     */
+    public int getBranchTypeValue() {
+      return branchType_;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch type.
+     * </pre>
+     *
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+     */
+    public Builder setBranchTypeValue(int value) {
+      branchType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch type.
+     * </pre>
+     *
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+      return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch type.
+     * </pre>
+     *
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+     */
+    public Builder setBranchType(io.seata.codec.protobuf.generated.BranchTypeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      branchType_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Branch type.
+     * </pre>
+     *
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+     */
+    public Builder clearBranchType() {
+      
+      branchType_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object resourceId_ = "";
+    /**
+     * <pre>
+     **
+     * The Resource id.
+     * </pre>
+     *
+     * <code>string resourceId = 5;</code>
+     */
+    public java.lang.String getResourceId() {
+      java.lang.Object ref = resourceId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        resourceId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     **
+     * The Resource id.
+     * </pre>
+     *
+     * <code>string resourceId = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getResourceIdBytes() {
+      java.lang.Object ref = resourceId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        resourceId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     **
+     * The Resource id.
+     * </pre>
+     *
+     * <code>string resourceId = 5;</code>
+     */
+    public Builder setResourceId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Resource id.
+     * </pre>
+     *
+     * <code>string resourceId = 5;</code>
+     */
+    public Builder clearResourceId() {
+      
+      resourceId_ = getDefaultInstance().getResourceId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Resource id.
+     * </pre>
+     *
+     * <code>string resourceId = 5;</code>
+     */
+    public Builder setResourceIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object applicationData_ = "";
+    /**
+     * <pre>
+     **
+     * The Application data.
+     * </pre>
+     *
+     * <code>string applicationData = 6;</code>
+     */
+    public java.lang.String getApplicationData() {
+      java.lang.Object ref = applicationData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        applicationData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <pre>
+     **
+     * The Application data.
+     * </pre>
+     *
+     * <code>string applicationData = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getApplicationDataBytes() {
+      java.lang.Object ref = applicationData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        applicationData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <pre>
+     **
+     * The Application data.
+     * </pre>
+     *
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Application data.
+     * </pre>
+     *
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder clearApplicationData() {
+      
+      applicationData_ = getDefaultInstance().getApplicationData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     **
+     * The Application data.
+     * </pre>
+     *
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractBranchEndRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractBranchEndRequestProto)
+  private static final io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractBranchEndRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractBranchEndRequestProto>() {
+    @java.lang.Override
+    public AbstractBranchEndRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractBranchEndRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractBranchEndRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractBranchEndRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..add774f2dc5190b747f334be5a0c1bd6d981a113
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndRequestProtoOrBuilder.java
@@ -0,0 +1,101 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractBranchEndRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractBranchEndRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  boolean hasAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <pre>
+   **
+   * The Branch id.
+   * </pre>
+   *
+   * <code>int64 branchId = 3;</code>
+   */
+  long getBranchId();
+
+  /**
+   * <pre>
+   **
+   * The Branch type.
+   * </pre>
+   *
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+   */
+  int getBranchTypeValue();
+  /**
+   * <pre>
+   **
+   * The Branch type.
+   * </pre>
+   *
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 4;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchTypeProto getBranchType();
+
+  /**
+   * <pre>
+   **
+   * The Resource id.
+   * </pre>
+   *
+   * <code>string resourceId = 5;</code>
+   */
+  java.lang.String getResourceId();
+  /**
+   * <pre>
+   **
+   * The Resource id.
+   * </pre>
+   *
+   * <code>string resourceId = 5;</code>
+   */
+  com.google.protobuf.ByteString
+      getResourceIdBytes();
+
+  /**
+   * <pre>
+   **
+   * The Application data.
+   * </pre>
+   *
+   * <code>string applicationData = 6;</code>
+   */
+  java.lang.String getApplicationData();
+  /**
+   * <pre>
+   **
+   * The Application data.
+   * </pre>
+   *
+   * <code>string applicationData = 6;</code>
+   */
+  com.google.protobuf.ByteString
+      getApplicationDataBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..6af4ef672d3123a018978d7eccf32bb79e686362
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponse.java
@@ -0,0 +1,68 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractBranchEndResponse {
+  private AbstractBranchEndResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\037abstractBranchEndResponse.proto\022\032io.se" +
+      "ata.protocol.protobuf\032!abstractTransacti" +
+      "onResponse.proto\032\022branchStatus.proto\"\347\001\n" +
+      "\036AbstractBranchEndResponseProto\022a\n\033abstr" +
+      "actTransactionResponse\030\001 \001(\0132<.io.seata." +
+      "protocol.protobuf.AbstractTransactionRes" +
+      "ponseProto\022\013\n\003xid\030\002 \001(\t\022\020\n\010branchId\030\003 \001(" +
+      "\003\022C\n\014branchStatus\030\004 \001(\0162-.io.seata.proto" +
+      "col.protobuf.BranchStatusProtoB@\n!io.sea" +
+      "ta.codec.protobuf.generatedB\031AbstractBra" +
+      "nchEndResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+          io.seata.codec.protobuf.generated.BranchStatus.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", "Xid", "BranchId", "BranchStatus", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+    io.seata.codec.protobuf.generated.BranchStatus.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..b206980cac686c4a1130becdb7bf49dfaf23138d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProto.java
@@ -0,0 +1,872 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractBranchEndResponseProto}
+ */
+public  final class AbstractBranchEndResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractBranchEndResponseProto)
+    AbstractBranchEndResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractBranchEndResponseProto.newBuilder() to construct.
+  private AbstractBranchEndResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractBranchEndResponseProto() {
+    xid_ = "";
+    branchStatus_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractBranchEndResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 24: {
+
+            branchId_ = input.readInt64();
+            break;
+          }
+          case 32: {
+            int rawValue = input.readEnum();
+
+            branchStatus_ = rawValue;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractBranchEndResponse.internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractBranchEndResponse.internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.class, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int BRANCHID_FIELD_NUMBER = 3;
+  private long branchId_;
+  /**
+   * <code>int64 branchId = 3;</code>
+   */
+  public long getBranchId() {
+    return branchId_;
+  }
+
+  public static final int BRANCHSTATUS_FIELD_NUMBER = 4;
+  private int branchStatus_;
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+   */
+  public int getBranchStatusValue() {
+    return branchStatus_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchStatusProto getBranchStatus() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.BranchStatusProto result = io.seata.codec.protobuf.generated.BranchStatusProto.valueOf(branchStatus_);
+    return result == null ? io.seata.codec.protobuf.generated.BranchStatusProto.UNRECOGNIZED : result;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (branchId_ != 0L) {
+      output.writeInt64(3, branchId_);
+    }
+    if (branchStatus_ != io.seata.codec.protobuf.generated.BranchStatusProto.BUnknown.getNumber()) {
+      output.writeEnum(4, branchStatus_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (branchId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, branchId_);
+    }
+    if (branchStatus_ != io.seata.codec.protobuf.generated.BranchStatusProto.BUnknown.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(4, branchStatus_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto other = (io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (getBranchId()
+        != other.getBranchId()) return false;
+    if (branchStatus_ != other.branchStatus_) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + BRANCHID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getBranchId());
+    hash = (37 * hash) + BRANCHSTATUS_FIELD_NUMBER;
+    hash = (53 * hash) + branchStatus_;
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractBranchEndResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractBranchEndResponseProto)
+      io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndResponse.internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndResponse.internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.class, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      xid_ = "";
+
+      branchId_ = 0L;
+
+      branchStatus_ = 0;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndResponse.internal_static_io_seata_protocol_protobuf_AbstractBranchEndResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto build() {
+      io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto result = new io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.branchId_ = branchId_;
+      result.branchStatus_ = branchStatus_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (other.getBranchId() != 0L) {
+        setBranchId(other.getBranchId());
+      }
+      if (other.branchStatus_ != 0) {
+        setBranchStatusValue(other.getBranchStatusValue());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private long branchId_ ;
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public long getBranchId() {
+      return branchId_;
+    }
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder setBranchId(long value) {
+      
+      branchId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder clearBranchId() {
+      
+      branchId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private int branchStatus_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+     */
+    public int getBranchStatusValue() {
+      return branchStatus_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+     */
+    public Builder setBranchStatusValue(int value) {
+      branchStatus_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchStatusProto getBranchStatus() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.BranchStatusProto result = io.seata.codec.protobuf.generated.BranchStatusProto.valueOf(branchStatus_);
+      return result == null ? io.seata.codec.protobuf.generated.BranchStatusProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+     */
+    public Builder setBranchStatus(io.seata.codec.protobuf.generated.BranchStatusProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      branchStatus_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+     */
+    public Builder clearBranchStatus() {
+      
+      branchStatus_ = 0;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractBranchEndResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractBranchEndResponseProto)
+  private static final io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractBranchEndResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractBranchEndResponseProto>() {
+    @java.lang.Override
+    public AbstractBranchEndResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractBranchEndResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractBranchEndResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractBranchEndResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..7247aa323c7bf394b49f1c46787d326842d2d058
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractBranchEndResponseProtoOrBuilder.java
@@ -0,0 +1,46 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractBranchEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractBranchEndResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractBranchEndResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <code>int64 branchId = 3;</code>
+   */
+  long getBranchId();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+   */
+  int getBranchStatusValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto branchStatus = 4;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchStatusProto getBranchStatus();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7925b0ec6ebdecb8df3964b2890d1fdc2126015e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequest.java
@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractGlobalEndRequest {
+  private AbstractGlobalEndRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\036abstractGlobalEndRequest.proto\022\032io.sea" +
+      "ta.protocol.protobuf\032 abstractTransactio" +
+      "nRequest.proto\"\240\001\n\035AbstractGlobalEndRequ" +
+      "estProto\022_\n\032abstractTransactionRequest\030\001" +
+      " \001(\0132;.io.seata.protocol.protobuf.Abstra" +
+      "ctTransactionRequestProto\022\013\n\003xid\030\002 \001(\t\022\021" +
+      "\n\textraData\030\003 \001(\tB?\n!io.seata.codec.prot" +
+      "obuf.generatedB\030AbstractGlobalEndRequest" +
+      "P\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionRequest", "Xid", "ExtraData", });
+    io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..c005bc52227068e405ad67335698b12eadb0691c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProto.java
@@ -0,0 +1,856 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractGlobalEndRequestProto}
+ */
+public  final class AbstractGlobalEndRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractGlobalEndRequestProto)
+    AbstractGlobalEndRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractGlobalEndRequestProto.newBuilder() to construct.
+  private AbstractGlobalEndRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractGlobalEndRequestProto() {
+    xid_ = "";
+    extraData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractGlobalEndRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder subBuilder = null;
+            if (abstractTransactionRequest_ != null) {
+              subBuilder = abstractTransactionRequest_.toBuilder();
+            }
+            abstractTransactionRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionRequest_);
+              abstractTransactionRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            extraData_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.class, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public boolean hasAbstractTransactionRequest() {
+    return abstractTransactionRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+    return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+    return getAbstractTransactionRequest();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int EXTRADATA_FIELD_NUMBER = 3;
+  private volatile java.lang.Object extraData_;
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public java.lang.String getExtraData() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      extraData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getExtraDataBytes() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      extraData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionRequest_ != null) {
+      output.writeMessage(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, extraData_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, extraData_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto other = (io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto) obj;
+
+    if (hasAbstractTransactionRequest() != other.hasAbstractTransactionRequest()) return false;
+    if (hasAbstractTransactionRequest()) {
+      if (!getAbstractTransactionRequest()
+          .equals(other.getAbstractTransactionRequest())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (!getExtraData()
+        .equals(other.getExtraData())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionRequest()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionRequest().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + EXTRADATA_FIELD_NUMBER;
+    hash = (53 * hash) + getExtraData().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractGlobalEndRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractGlobalEndRequestProto)
+      io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.class, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+      xid_ = "";
+
+      extraData_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto build() {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto result = new io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto(this);
+      if (abstractTransactionRequestBuilder_ == null) {
+        result.abstractTransactionRequest_ = abstractTransactionRequest_;
+      } else {
+        result.abstractTransactionRequest_ = abstractTransactionRequestBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.extraData_ = extraData_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionRequest()) {
+        mergeAbstractTransactionRequest(other.getAbstractTransactionRequest());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (!other.getExtraData().isEmpty()) {
+        extraData_ = other.extraData_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> abstractTransactionRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public boolean hasAbstractTransactionRequest() {
+      return abstractTransactionRequestBuilder_ != null || abstractTransactionRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      } else {
+        return abstractTransactionRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionRequest_ = value;
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder builderForValue) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder mergeAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (abstractTransactionRequest_ != null) {
+          abstractTransactionRequest_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder(abstractTransactionRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder clearAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+        onChanged();
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder getAbstractTransactionRequestBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+      if (abstractTransactionRequestBuilder_ != null) {
+        return abstractTransactionRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> 
+        getAbstractTransactionRequestFieldBuilder() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder>(
+                getAbstractTransactionRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionRequest_ = null;
+      }
+      return abstractTransactionRequestBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object extraData_ = "";
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public java.lang.String getExtraData() {
+      java.lang.Object ref = extraData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        extraData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getExtraDataBytes() {
+      java.lang.Object ref = extraData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        extraData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder clearExtraData() {
+      
+      extraData_ = getDefaultInstance().getExtraData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractGlobalEndRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractGlobalEndRequestProto)
+  private static final io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractGlobalEndRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractGlobalEndRequestProto>() {
+    @java.lang.Override
+    public AbstractGlobalEndRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractGlobalEndRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractGlobalEndRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractGlobalEndRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..8bdd256de20e51a32076ab1f256c0f7d8ae45227
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndRequestProtoOrBuilder.java
@@ -0,0 +1,42 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractGlobalEndRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractGlobalEndRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  boolean hasAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  java.lang.String getExtraData();
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getExtraDataBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb183b7a64b6a402c3c23846dd7eb80adc2051fa
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponse.java
@@ -0,0 +1,67 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractGlobalEndResponse {
+  private AbstractGlobalEndResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\037abstractGlobalEndResponse.proto\022\032io.se" +
+      "ata.protocol.protobuf\032!abstractTransacti" +
+      "onResponse.proto\032\022globalStatus.proto\"\310\001\n" +
+      "\036AbstractGlobalEndResponseProto\022a\n\033abstr" +
+      "actTransactionResponse\030\001 \001(\0132<.io.seata." +
+      "protocol.protobuf.AbstractTransactionRes" +
+      "ponseProto\022C\n\014globalStatus\030\002 \001(\0162-.io.se" +
+      "ata.protocol.protobuf.GlobalStatusProtoB" +
+      "@\n!io.seata.codec.protobuf.generatedB\031Ab" +
+      "stractGlobalEndResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+          io.seata.codec.protobuf.generated.GlobalStatus.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", "GlobalStatus", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+    io.seata.codec.protobuf.generated.GlobalStatus.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..86a100786a57ecf8d7b30f46022c99089d4a6066
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProto.java
@@ -0,0 +1,687 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractGlobalEndResponseProto}
+ */
+public  final class AbstractGlobalEndResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractGlobalEndResponseProto)
+    AbstractGlobalEndResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractGlobalEndResponseProto.newBuilder() to construct.
+  private AbstractGlobalEndResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractGlobalEndResponseProto() {
+    globalStatus_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractGlobalEndResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+            int rawValue = input.readEnum();
+
+            globalStatus_ = rawValue;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.class, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  public static final int GLOBALSTATUS_FIELD_NUMBER = 2;
+  private int globalStatus_;
+  /**
+   * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+   */
+  public int getGlobalStatusValue() {
+    return globalStatus_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+   */
+  public io.seata.codec.protobuf.generated.GlobalStatusProto getGlobalStatus() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.GlobalStatusProto result = io.seata.codec.protobuf.generated.GlobalStatusProto.valueOf(globalStatus_);
+    return result == null ? io.seata.codec.protobuf.generated.GlobalStatusProto.UNRECOGNIZED : result;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    if (globalStatus_ != io.seata.codec.protobuf.generated.GlobalStatusProto.UnKnown.getNumber()) {
+      output.writeEnum(2, globalStatus_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    if (globalStatus_ != io.seata.codec.protobuf.generated.GlobalStatusProto.UnKnown.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(2, globalStatus_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto other = (io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (globalStatus_ != other.globalStatus_) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (37 * hash) + GLOBALSTATUS_FIELD_NUMBER;
+    hash = (53 * hash) + globalStatus_;
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractGlobalEndResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractGlobalEndResponseProto)
+      io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.class, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      globalStatus_ = 0;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.internal_static_io_seata_protocol_protobuf_AbstractGlobalEndResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto build() {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto result = new io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      result.globalStatus_ = globalStatus_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      if (other.globalStatus_ != 0) {
+        setGlobalStatusValue(other.getGlobalStatusValue());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+
+    private int globalStatus_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+     */
+    public int getGlobalStatusValue() {
+      return globalStatus_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+     */
+    public Builder setGlobalStatusValue(int value) {
+      globalStatus_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+     */
+    public io.seata.codec.protobuf.generated.GlobalStatusProto getGlobalStatus() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.GlobalStatusProto result = io.seata.codec.protobuf.generated.GlobalStatusProto.valueOf(globalStatus_);
+      return result == null ? io.seata.codec.protobuf.generated.GlobalStatusProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+     */
+    public Builder setGlobalStatus(io.seata.codec.protobuf.generated.GlobalStatusProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      globalStatus_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+     */
+    public Builder clearGlobalStatus() {
+      
+      globalStatus_ = 0;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractGlobalEndResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractGlobalEndResponseProto)
+  private static final io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractGlobalEndResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractGlobalEndResponseProto>() {
+    @java.lang.Override
+    public AbstractGlobalEndResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractGlobalEndResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractGlobalEndResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractGlobalEndResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..a4b9294a4013ba0bb366caf5db94b34def5e18d6
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractGlobalEndResponseProtoOrBuilder.java
@@ -0,0 +1,31 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractGlobalEndResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractGlobalEndResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractGlobalEndResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+   */
+  int getGlobalStatusValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.GlobalStatusProto globalStatus = 2;</code>
+   */
+  io.seata.codec.protobuf.generated.GlobalStatusProto getGlobalStatus();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..723c92d908a90bf0743e7a539a82a6d277f8cf16
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequest.java
@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractIdentifyRequest {
+  private AbstractIdentifyRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\035abstractIdentifyRequest.proto\022\032io.seat" +
+      "a.protocol.protobuf\032\025abstractMessage.pro" +
+      "to\"\305\001\n\034AbstractIdentifyRequestProto\022I\n\017a" +
+      "bstractMessage\030\001 \001(\01320.io.seata.protocol" +
+      ".protobuf.AbstractMessageProto\022\017\n\007versio" +
+      "n\030\002 \001(\t\022\025\n\rapplicationId\030\003 \001(\t\022\037\n\027transa" +
+      "ctionServiceGroup\030\004 \001(\t\022\021\n\textraData\030\005 \001" +
+      "(\tB>\n!io.seata.codec.protobuf.generatedB" +
+      "\027AbstractIdentifyRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor,
+        new java.lang.String[] { "AbstractMessage", "Version", "ApplicationId", "TransactionServiceGroup", "ExtraData", });
+    io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e48f96410a87a60187efa855e46219cf4b2dbdb4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProto.java
@@ -0,0 +1,1110 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractIdentifyRequestProto}
+ */
+public  final class AbstractIdentifyRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractIdentifyRequestProto)
+    AbstractIdentifyRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractIdentifyRequestProto.newBuilder() to construct.
+  private AbstractIdentifyRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractIdentifyRequestProto() {
+    version_ = "";
+    applicationId_ = "";
+    transactionServiceGroup_ = "";
+    extraData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractIdentifyRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractMessageProto.Builder subBuilder = null;
+            if (abstractMessage_ != null) {
+              subBuilder = abstractMessage_.toBuilder();
+            }
+            abstractMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractMessage_);
+              abstractMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            version_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            applicationId_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            transactionServiceGroup_ = s;
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            extraData_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractIdentifyRequest.internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractIdentifyRequest.internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.class, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public boolean hasAbstractMessage() {
+    return abstractMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+    return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+    return getAbstractMessage();
+  }
+
+  public static final int VERSION_FIELD_NUMBER = 2;
+  private volatile java.lang.Object version_;
+  /**
+   * <code>string version = 2;</code>
+   */
+  public java.lang.String getVersion() {
+    java.lang.Object ref = version_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      version_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string version = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getVersionBytes() {
+    java.lang.Object ref = version_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      version_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int APPLICATIONID_FIELD_NUMBER = 3;
+  private volatile java.lang.Object applicationId_;
+  /**
+   * <code>string applicationId = 3;</code>
+   */
+  public java.lang.String getApplicationId() {
+    java.lang.Object ref = applicationId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      applicationId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string applicationId = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getApplicationIdBytes() {
+    java.lang.Object ref = applicationId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      applicationId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int TRANSACTIONSERVICEGROUP_FIELD_NUMBER = 4;
+  private volatile java.lang.Object transactionServiceGroup_;
+  /**
+   * <code>string transactionServiceGroup = 4;</code>
+   */
+  public java.lang.String getTransactionServiceGroup() {
+    java.lang.Object ref = transactionServiceGroup_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      transactionServiceGroup_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string transactionServiceGroup = 4;</code>
+   */
+  public com.google.protobuf.ByteString
+      getTransactionServiceGroupBytes() {
+    java.lang.Object ref = transactionServiceGroup_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      transactionServiceGroup_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int EXTRADATA_FIELD_NUMBER = 5;
+  private volatile java.lang.Object extraData_;
+  /**
+   * <code>string extraData = 5;</code>
+   */
+  public java.lang.String getExtraData() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      extraData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string extraData = 5;</code>
+   */
+  public com.google.protobuf.ByteString
+      getExtraDataBytes() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      extraData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractMessage_ != null) {
+      output.writeMessage(1, getAbstractMessage());
+    }
+    if (!getVersionBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, version_);
+    }
+    if (!getApplicationIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, applicationId_);
+    }
+    if (!getTransactionServiceGroupBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, transactionServiceGroup_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, extraData_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractMessage());
+    }
+    if (!getVersionBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, version_);
+    }
+    if (!getApplicationIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, applicationId_);
+    }
+    if (!getTransactionServiceGroupBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, transactionServiceGroup_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, extraData_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto other = (io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto) obj;
+
+    if (hasAbstractMessage() != other.hasAbstractMessage()) return false;
+    if (hasAbstractMessage()) {
+      if (!getAbstractMessage()
+          .equals(other.getAbstractMessage())) return false;
+    }
+    if (!getVersion()
+        .equals(other.getVersion())) return false;
+    if (!getApplicationId()
+        .equals(other.getApplicationId())) return false;
+    if (!getTransactionServiceGroup()
+        .equals(other.getTransactionServiceGroup())) return false;
+    if (!getExtraData()
+        .equals(other.getExtraData())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractMessage()) {
+      hash = (37 * hash) + ABSTRACTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractMessage().hashCode();
+    }
+    hash = (37 * hash) + VERSION_FIELD_NUMBER;
+    hash = (53 * hash) + getVersion().hashCode();
+    hash = (37 * hash) + APPLICATIONID_FIELD_NUMBER;
+    hash = (53 * hash) + getApplicationId().hashCode();
+    hash = (37 * hash) + TRANSACTIONSERVICEGROUP_FIELD_NUMBER;
+    hash = (53 * hash) + getTransactionServiceGroup().hashCode();
+    hash = (37 * hash) + EXTRADATA_FIELD_NUMBER;
+    hash = (53 * hash) + getExtraData().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractIdentifyRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractIdentifyRequestProto)
+      io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyRequest.internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyRequest.internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.class, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+      version_ = "";
+
+      applicationId_ = "";
+
+      transactionServiceGroup_ = "";
+
+      extraData_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyRequest.internal_static_io_seata_protocol_protobuf_AbstractIdentifyRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto build() {
+      io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto result = new io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto(this);
+      if (abstractMessageBuilder_ == null) {
+        result.abstractMessage_ = abstractMessage_;
+      } else {
+        result.abstractMessage_ = abstractMessageBuilder_.build();
+      }
+      result.version_ = version_;
+      result.applicationId_ = applicationId_;
+      result.transactionServiceGroup_ = transactionServiceGroup_;
+      result.extraData_ = extraData_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractMessage()) {
+        mergeAbstractMessage(other.getAbstractMessage());
+      }
+      if (!other.getVersion().isEmpty()) {
+        version_ = other.version_;
+        onChanged();
+      }
+      if (!other.getApplicationId().isEmpty()) {
+        applicationId_ = other.applicationId_;
+        onChanged();
+      }
+      if (!other.getTransactionServiceGroup().isEmpty()) {
+        transactionServiceGroup_ = other.transactionServiceGroup_;
+        onChanged();
+      }
+      if (!other.getExtraData().isEmpty()) {
+        extraData_ = other.extraData_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> abstractMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public boolean hasAbstractMessage() {
+      return abstractMessageBuilder_ != null || abstractMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      } else {
+        return abstractMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractMessage_ = value;
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(
+        io.seata.codec.protobuf.generated.AbstractMessageProto.Builder builderForValue) {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder mergeAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (abstractMessage_ != null) {
+          abstractMessage_ =
+            io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder(abstractMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder clearAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+        onChanged();
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto.Builder getAbstractMessageBuilder() {
+      
+      onChanged();
+      return getAbstractMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+      if (abstractMessageBuilder_ != null) {
+        return abstractMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> 
+        getAbstractMessageFieldBuilder() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder>(
+                getAbstractMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractMessage_ = null;
+      }
+      return abstractMessageBuilder_;
+    }
+
+    private java.lang.Object version_ = "";
+    /**
+     * <code>string version = 2;</code>
+     */
+    public java.lang.String getVersion() {
+      java.lang.Object ref = version_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        version_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getVersionBytes() {
+      java.lang.Object ref = version_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        version_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder setVersion(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      version_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder clearVersion() {
+      
+      version_ = getDefaultInstance().getVersion();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder setVersionBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      version_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object applicationId_ = "";
+    /**
+     * <code>string applicationId = 3;</code>
+     */
+    public java.lang.String getApplicationId() {
+      java.lang.Object ref = applicationId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        applicationId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string applicationId = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getApplicationIdBytes() {
+      java.lang.Object ref = applicationId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        applicationId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string applicationId = 3;</code>
+     */
+    public Builder setApplicationId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      applicationId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationId = 3;</code>
+     */
+    public Builder clearApplicationId() {
+      
+      applicationId_ = getDefaultInstance().getApplicationId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationId = 3;</code>
+     */
+    public Builder setApplicationIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      applicationId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object transactionServiceGroup_ = "";
+    /**
+     * <code>string transactionServiceGroup = 4;</code>
+     */
+    public java.lang.String getTransactionServiceGroup() {
+      java.lang.Object ref = transactionServiceGroup_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        transactionServiceGroup_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string transactionServiceGroup = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTransactionServiceGroupBytes() {
+      java.lang.Object ref = transactionServiceGroup_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        transactionServiceGroup_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string transactionServiceGroup = 4;</code>
+     */
+    public Builder setTransactionServiceGroup(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      transactionServiceGroup_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string transactionServiceGroup = 4;</code>
+     */
+    public Builder clearTransactionServiceGroup() {
+      
+      transactionServiceGroup_ = getDefaultInstance().getTransactionServiceGroup();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string transactionServiceGroup = 4;</code>
+     */
+    public Builder setTransactionServiceGroupBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      transactionServiceGroup_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object extraData_ = "";
+    /**
+     * <code>string extraData = 5;</code>
+     */
+    public java.lang.String getExtraData() {
+      java.lang.Object ref = extraData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        extraData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getExtraDataBytes() {
+      java.lang.Object ref = extraData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        extraData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 5;</code>
+     */
+    public Builder setExtraData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 5;</code>
+     */
+    public Builder clearExtraData() {
+      
+      extraData_ = getDefaultInstance().getExtraData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 5;</code>
+     */
+    public Builder setExtraDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractIdentifyRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractIdentifyRequestProto)
+  private static final io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractIdentifyRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractIdentifyRequestProto>() {
+    @java.lang.Override
+    public AbstractIdentifyRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractIdentifyRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractIdentifyRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractIdentifyRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..e589eb735cf1e34dbf528e8925c5ffc708ce96bc
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyRequestProtoOrBuilder.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractIdentifyRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractIdentifyRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  boolean hasAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder();
+
+  /**
+   * <code>string version = 2;</code>
+   */
+  java.lang.String getVersion();
+  /**
+   * <code>string version = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getVersionBytes();
+
+  /**
+   * <code>string applicationId = 3;</code>
+   */
+  java.lang.String getApplicationId();
+  /**
+   * <code>string applicationId = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getApplicationIdBytes();
+
+  /**
+   * <code>string transactionServiceGroup = 4;</code>
+   */
+  java.lang.String getTransactionServiceGroup();
+  /**
+   * <code>string transactionServiceGroup = 4;</code>
+   */
+  com.google.protobuf.ByteString
+      getTransactionServiceGroupBytes();
+
+  /**
+   * <code>string extraData = 5;</code>
+   */
+  java.lang.String getExtraData();
+  /**
+   * <code>string extraData = 5;</code>
+   */
+  com.google.protobuf.ByteString
+      getExtraDataBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1a43ca7b4393acf4f439b4185e62a95c163ddb4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponse.java
@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractIdentifyResponse {
+  private AbstractIdentifyResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\036abstractIdentifyResponse.proto\022\032io.sea" +
+      "ta.protocol.protobuf\032\033abstractResultMess" +
+      "age.proto\"\256\001\n\035AbstractIdentifyResponsePr" +
+      "oto\022U\n\025abstractResultMessage\030\001 \001(\01326.io." +
+      "seata.protocol.protobuf.AbstractResultMe" +
+      "ssageProto\022\017\n\007version\030\002 \001(\t\022\021\n\textraData" +
+      "\030\003 \001(\t\022\022\n\nidentified\030\004 \001(\010B?\n!io.seata.c" +
+      "odec.protobuf.generatedB\030AbstractIdentif" +
+      "yResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractResultMessage.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor,
+        new java.lang.String[] { "AbstractResultMessage", "Version", "ExtraData", "Identified", });
+    io.seata.codec.protobuf.generated.AbstractResultMessage.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..95f4c31fe79b34d79bc478ebf3f65be2188445c3
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProto.java
@@ -0,0 +1,914 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractIdentifyResponseProto}
+ */
+public  final class AbstractIdentifyResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractIdentifyResponseProto)
+    AbstractIdentifyResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractIdentifyResponseProto.newBuilder() to construct.
+  private AbstractIdentifyResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractIdentifyResponseProto() {
+    version_ = "";
+    extraData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractIdentifyResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder subBuilder = null;
+            if (abstractResultMessage_ != null) {
+              subBuilder = abstractResultMessage_.toBuilder();
+            }
+            abstractResultMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractResultMessage_);
+              abstractResultMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            version_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            extraData_ = s;
+            break;
+          }
+          case 32: {
+
+            identified_ = input.readBool();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractIdentifyResponse.internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractIdentifyResponse.internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.class, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTRESULTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractResultMessageProto abstractResultMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public boolean hasAbstractResultMessage() {
+    return abstractResultMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage() {
+    return abstractResultMessage_ == null ? io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder() {
+    return getAbstractResultMessage();
+  }
+
+  public static final int VERSION_FIELD_NUMBER = 2;
+  private volatile java.lang.Object version_;
+  /**
+   * <code>string version = 2;</code>
+   */
+  public java.lang.String getVersion() {
+    java.lang.Object ref = version_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      version_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string version = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getVersionBytes() {
+    java.lang.Object ref = version_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      version_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int EXTRADATA_FIELD_NUMBER = 3;
+  private volatile java.lang.Object extraData_;
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public java.lang.String getExtraData() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      extraData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getExtraDataBytes() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      extraData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int IDENTIFIED_FIELD_NUMBER = 4;
+  private boolean identified_;
+  /**
+   * <code>bool identified = 4;</code>
+   */
+  public boolean getIdentified() {
+    return identified_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractResultMessage_ != null) {
+      output.writeMessage(1, getAbstractResultMessage());
+    }
+    if (!getVersionBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, version_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, extraData_);
+    }
+    if (identified_ != false) {
+      output.writeBool(4, identified_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractResultMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractResultMessage());
+    }
+    if (!getVersionBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, version_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, extraData_);
+    }
+    if (identified_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(4, identified_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto other = (io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto) obj;
+
+    if (hasAbstractResultMessage() != other.hasAbstractResultMessage()) return false;
+    if (hasAbstractResultMessage()) {
+      if (!getAbstractResultMessage()
+          .equals(other.getAbstractResultMessage())) return false;
+    }
+    if (!getVersion()
+        .equals(other.getVersion())) return false;
+    if (!getExtraData()
+        .equals(other.getExtraData())) return false;
+    if (getIdentified()
+        != other.getIdentified()) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractResultMessage()) {
+      hash = (37 * hash) + ABSTRACTRESULTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractResultMessage().hashCode();
+    }
+    hash = (37 * hash) + VERSION_FIELD_NUMBER;
+    hash = (53 * hash) + getVersion().hashCode();
+    hash = (37 * hash) + EXTRADATA_FIELD_NUMBER;
+    hash = (53 * hash) + getExtraData().hashCode();
+    hash = (37 * hash) + IDENTIFIED_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getIdentified());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractIdentifyResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractIdentifyResponseProto)
+      io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyResponse.internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyResponse.internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.class, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = null;
+      } else {
+        abstractResultMessage_ = null;
+        abstractResultMessageBuilder_ = null;
+      }
+      version_ = "";
+
+      extraData_ = "";
+
+      identified_ = false;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyResponse.internal_static_io_seata_protocol_protobuf_AbstractIdentifyResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto build() {
+      io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto result = new io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto(this);
+      if (abstractResultMessageBuilder_ == null) {
+        result.abstractResultMessage_ = abstractResultMessage_;
+      } else {
+        result.abstractResultMessage_ = abstractResultMessageBuilder_.build();
+      }
+      result.version_ = version_;
+      result.extraData_ = extraData_;
+      result.identified_ = identified_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractResultMessage()) {
+        mergeAbstractResultMessage(other.getAbstractResultMessage());
+      }
+      if (!other.getVersion().isEmpty()) {
+        version_ = other.version_;
+        onChanged();
+      }
+      if (!other.getExtraData().isEmpty()) {
+        extraData_ = other.extraData_;
+        onChanged();
+      }
+      if (other.getIdentified() != false) {
+        setIdentified(other.getIdentified());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractResultMessageProto abstractResultMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder> abstractResultMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public boolean hasAbstractResultMessage() {
+      return abstractResultMessageBuilder_ != null || abstractResultMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage() {
+      if (abstractResultMessageBuilder_ == null) {
+        return abstractResultMessage_ == null ? io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+      } else {
+        return abstractResultMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder setAbstractResultMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto value) {
+      if (abstractResultMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractResultMessage_ = value;
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder setAbstractResultMessage(
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder builderForValue) {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder mergeAbstractResultMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto value) {
+      if (abstractResultMessageBuilder_ == null) {
+        if (abstractResultMessage_ != null) {
+          abstractResultMessage_ =
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.newBuilder(abstractResultMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractResultMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder clearAbstractResultMessage() {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = null;
+        onChanged();
+      } else {
+        abstractResultMessage_ = null;
+        abstractResultMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder getAbstractResultMessageBuilder() {
+      
+      onChanged();
+      return getAbstractResultMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder() {
+      if (abstractResultMessageBuilder_ != null) {
+        return abstractResultMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractResultMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder> 
+        getAbstractResultMessageFieldBuilder() {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder>(
+                getAbstractResultMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractResultMessage_ = null;
+      }
+      return abstractResultMessageBuilder_;
+    }
+
+    private java.lang.Object version_ = "";
+    /**
+     * <code>string version = 2;</code>
+     */
+    public java.lang.String getVersion() {
+      java.lang.Object ref = version_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        version_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getVersionBytes() {
+      java.lang.Object ref = version_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        version_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder setVersion(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      version_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder clearVersion() {
+      
+      version_ = getDefaultInstance().getVersion();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string version = 2;</code>
+     */
+    public Builder setVersionBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      version_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object extraData_ = "";
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public java.lang.String getExtraData() {
+      java.lang.Object ref = extraData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        extraData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getExtraDataBytes() {
+      java.lang.Object ref = extraData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        extraData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder clearExtraData() {
+      
+      extraData_ = getDefaultInstance().getExtraData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+
+    private boolean identified_ ;
+    /**
+     * <code>bool identified = 4;</code>
+     */
+    public boolean getIdentified() {
+      return identified_;
+    }
+    /**
+     * <code>bool identified = 4;</code>
+     */
+    public Builder setIdentified(boolean value) {
+      
+      identified_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>bool identified = 4;</code>
+     */
+    public Builder clearIdentified() {
+      
+      identified_ = false;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractIdentifyResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractIdentifyResponseProto)
+  private static final io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractIdentifyResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractIdentifyResponseProto>() {
+    @java.lang.Override
+    public AbstractIdentifyResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractIdentifyResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractIdentifyResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractIdentifyResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a98b2e4f0ef4ee4574fb6101c4fa282ae13e6d0
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractIdentifyResponseProtoOrBuilder.java
@@ -0,0 +1,47 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractIdentifyResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractIdentifyResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractIdentifyResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  boolean hasAbstractResultMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder();
+
+  /**
+   * <code>string version = 2;</code>
+   */
+  java.lang.String getVersion();
+  /**
+   * <code>string version = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getVersionBytes();
+
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  java.lang.String getExtraData();
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getExtraDataBytes();
+
+  /**
+   * <code>bool identified = 4;</code>
+   */
+  boolean getIdentified();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessage.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..b2cb60e3d96b0eab50343a80e7d511c519967db0
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessage.java
@@ -0,0 +1,61 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractMessage {
+  private AbstractMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractMessageProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\025abstractMessage.proto\022\032io.seata.protoc" +
+      "ol.protobuf\032\021messageType.proto\"Y\n\024Abstra" +
+      "ctMessageProto\022A\n\013messageType\030\001 \001(\0162,.io" +
+      ".seata.protocol.protobuf.MessageTypeProt" +
+      "oB6\n!io.seata.codec.protobuf.generatedB\017" +
+      "AbstractMessageP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.MessageType.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractMessageProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor,
+        new java.lang.String[] { "MessageType", });
+    io.seata.codec.protobuf.generated.MessageType.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..0dfa59da2251cadb6fa73c48d7de33b288f0f879
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProto.java
@@ -0,0 +1,506 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractMessageProto}
+ */
+public  final class AbstractMessageProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractMessageProto)
+    AbstractMessageProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractMessageProto.newBuilder() to construct.
+  private AbstractMessageProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractMessageProto() {
+    messageType_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractMessageProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+            int rawValue = input.readEnum();
+
+            messageType_ = rawValue;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractMessage.internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractMessage.internal_static_io_seata_protocol_protobuf_AbstractMessageProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractMessageProto.class, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder.class);
+  }
+
+  public static final int MESSAGETYPE_FIELD_NUMBER = 1;
+  private int messageType_;
+  /**
+   * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+   */
+  public int getMessageTypeValue() {
+    return messageType_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.MessageTypeProto getMessageType() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.MessageTypeProto result = io.seata.codec.protobuf.generated.MessageTypeProto.valueOf(messageType_);
+    return result == null ? io.seata.codec.protobuf.generated.MessageTypeProto.UNRECOGNIZED : result;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (messageType_ != io.seata.codec.protobuf.generated.MessageTypeProto.TYPE_GLOBAL_PRESERVED.getNumber()) {
+      output.writeEnum(1, messageType_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (messageType_ != io.seata.codec.protobuf.generated.MessageTypeProto.TYPE_GLOBAL_PRESERVED.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(1, messageType_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractMessageProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractMessageProto other = (io.seata.codec.protobuf.generated.AbstractMessageProto) obj;
+
+    if (messageType_ != other.messageType_) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + MESSAGETYPE_FIELD_NUMBER;
+    hash = (53 * hash) + messageType_;
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractMessageProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractMessageProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractMessageProto)
+      io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractMessage.internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractMessage.internal_static_io_seata_protocol_protobuf_AbstractMessageProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractMessageProto.class, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      messageType_ = 0;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractMessage.internal_static_io_seata_protocol_protobuf_AbstractMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractMessageProto build() {
+      io.seata.codec.protobuf.generated.AbstractMessageProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractMessageProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractMessageProto result = new io.seata.codec.protobuf.generated.AbstractMessageProto(this);
+      result.messageType_ = messageType_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractMessageProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractMessageProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractMessageProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance()) return this;
+      if (other.messageType_ != 0) {
+        setMessageTypeValue(other.getMessageTypeValue());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractMessageProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractMessageProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private int messageType_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+     */
+    public int getMessageTypeValue() {
+      return messageType_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+     */
+    public Builder setMessageTypeValue(int value) {
+      messageType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.MessageTypeProto getMessageType() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.MessageTypeProto result = io.seata.codec.protobuf.generated.MessageTypeProto.valueOf(messageType_);
+      return result == null ? io.seata.codec.protobuf.generated.MessageTypeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+     */
+    public Builder setMessageType(io.seata.codec.protobuf.generated.MessageTypeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      messageType_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+     */
+    public Builder clearMessageType() {
+      
+      messageType_ = 0;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractMessageProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractMessageProto)
+  private static final io.seata.codec.protobuf.generated.AbstractMessageProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractMessageProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractMessageProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractMessageProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractMessageProto>() {
+    @java.lang.Override
+    public AbstractMessageProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractMessageProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractMessageProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractMessageProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fd1dcd3361703be9c508b8259ed23329093eed8
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractMessageProtoOrBuilder.java
@@ -0,0 +1,18 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractMessageProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractMessageProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+   */
+  int getMessageTypeValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.MessageTypeProto messageType = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.MessageTypeProto getMessageType();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessage.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ea1900261270539eb7d6ea1ffb172360bc4229d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessage.java
@@ -0,0 +1,66 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractResultMessage {
+  private AbstractResultMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\033abstractResultMessage.proto\022\032io.seata." +
+      "protocol.protobuf\032\020resultCode.proto\032\025abs" +
+      "tractMessage.proto\"\265\001\n\032AbstractResultMes" +
+      "sageProto\022I\n\017AbstractMessage\030\001 \001(\01320.io." +
+      "seata.protocol.protobuf.AbstractMessageP" +
+      "roto\022?\n\nresultCode\030\002 \001(\0162+.io.seata.prot" +
+      "ocol.protobuf.ResultCodeProto\022\013\n\003msg\030\003 \001" +
+      "(\tB<\n!io.seata.codec.protobuf.generatedB" +
+      "\025AbstractResultMessageP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.ResultCode.getDescriptor(),
+          io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor,
+        new java.lang.String[] { "AbstractMessage", "ResultCode", "Msg", });
+    io.seata.codec.protobuf.generated.ResultCode.getDescriptor();
+    io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..226a373bc477ae75e340aede61d2a444e2759b6a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProto.java
@@ -0,0 +1,814 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractResultMessageProto}
+ */
+public  final class AbstractResultMessageProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractResultMessageProto)
+    AbstractResultMessageProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractResultMessageProto.newBuilder() to construct.
+  private AbstractResultMessageProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractResultMessageProto() {
+    resultCode_ = 0;
+    msg_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractResultMessageProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractMessageProto.Builder subBuilder = null;
+            if (abstractMessage_ != null) {
+              subBuilder = abstractMessage_.toBuilder();
+            }
+            abstractMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractMessage_);
+              abstractMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+            int rawValue = input.readEnum();
+
+            resultCode_ = rawValue;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            msg_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractResultMessage.internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractResultMessage.internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.class, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder.class);
+  }
+
+  public static final int ABSTRACTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  public boolean hasAbstractMessage() {
+    return abstractMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+    return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+    return getAbstractMessage();
+  }
+
+  public static final int RESULTCODE_FIELD_NUMBER = 2;
+  private int resultCode_;
+  /**
+   * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+   */
+  public int getResultCodeValue() {
+    return resultCode_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+   */
+  public io.seata.codec.protobuf.generated.ResultCodeProto getResultCode() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.ResultCodeProto result = io.seata.codec.protobuf.generated.ResultCodeProto.valueOf(resultCode_);
+    return result == null ? io.seata.codec.protobuf.generated.ResultCodeProto.UNRECOGNIZED : result;
+  }
+
+  public static final int MSG_FIELD_NUMBER = 3;
+  private volatile java.lang.Object msg_;
+  /**
+   * <code>string msg = 3;</code>
+   */
+  public java.lang.String getMsg() {
+    java.lang.Object ref = msg_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      msg_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string msg = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getMsgBytes() {
+    java.lang.Object ref = msg_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      msg_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractMessage_ != null) {
+      output.writeMessage(1, getAbstractMessage());
+    }
+    if (resultCode_ != io.seata.codec.protobuf.generated.ResultCodeProto.Failed.getNumber()) {
+      output.writeEnum(2, resultCode_);
+    }
+    if (!getMsgBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, msg_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractMessage());
+    }
+    if (resultCode_ != io.seata.codec.protobuf.generated.ResultCodeProto.Failed.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(2, resultCode_);
+    }
+    if (!getMsgBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, msg_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractResultMessageProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractResultMessageProto other = (io.seata.codec.protobuf.generated.AbstractResultMessageProto) obj;
+
+    if (hasAbstractMessage() != other.hasAbstractMessage()) return false;
+    if (hasAbstractMessage()) {
+      if (!getAbstractMessage()
+          .equals(other.getAbstractMessage())) return false;
+    }
+    if (resultCode_ != other.resultCode_) return false;
+    if (!getMsg()
+        .equals(other.getMsg())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractMessage()) {
+      hash = (37 * hash) + ABSTRACTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractMessage().hashCode();
+    }
+    hash = (37 * hash) + RESULTCODE_FIELD_NUMBER;
+    hash = (53 * hash) + resultCode_;
+    hash = (37 * hash) + MSG_FIELD_NUMBER;
+    hash = (53 * hash) + getMsg().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractResultMessageProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractResultMessageProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractResultMessageProto)
+      io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractResultMessage.internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractResultMessage.internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractResultMessageProto.class, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractResultMessageProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+      resultCode_ = 0;
+
+      msg_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractResultMessage.internal_static_io_seata_protocol_protobuf_AbstractResultMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto build() {
+      io.seata.codec.protobuf.generated.AbstractResultMessageProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractResultMessageProto result = new io.seata.codec.protobuf.generated.AbstractResultMessageProto(this);
+      if (abstractMessageBuilder_ == null) {
+        result.abstractMessage_ = abstractMessage_;
+      } else {
+        result.abstractMessage_ = abstractMessageBuilder_.build();
+      }
+      result.resultCode_ = resultCode_;
+      result.msg_ = msg_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractResultMessageProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractResultMessageProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractResultMessageProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance()) return this;
+      if (other.hasAbstractMessage()) {
+        mergeAbstractMessage(other.getAbstractMessage());
+      }
+      if (other.resultCode_ != 0) {
+        setResultCodeValue(other.getResultCodeValue());
+      }
+      if (!other.getMsg().isEmpty()) {
+        msg_ = other.msg_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractResultMessageProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractResultMessageProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> abstractMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public boolean hasAbstractMessage() {
+      return abstractMessageBuilder_ != null || abstractMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      } else {
+        return abstractMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractMessage_ = value;
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(
+        io.seata.codec.protobuf.generated.AbstractMessageProto.Builder builderForValue) {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public Builder mergeAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (abstractMessage_ != null) {
+          abstractMessage_ =
+            io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder(abstractMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public Builder clearAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+        onChanged();
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto.Builder getAbstractMessageBuilder() {
+      
+      onChanged();
+      return getAbstractMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+      if (abstractMessageBuilder_ != null) {
+        return abstractMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> 
+        getAbstractMessageFieldBuilder() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder>(
+                getAbstractMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractMessage_ = null;
+      }
+      return abstractMessageBuilder_;
+    }
+
+    private int resultCode_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+     */
+    public int getResultCodeValue() {
+      return resultCode_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+     */
+    public Builder setResultCodeValue(int value) {
+      resultCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+     */
+    public io.seata.codec.protobuf.generated.ResultCodeProto getResultCode() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.ResultCodeProto result = io.seata.codec.protobuf.generated.ResultCodeProto.valueOf(resultCode_);
+      return result == null ? io.seata.codec.protobuf.generated.ResultCodeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+     */
+    public Builder setResultCode(io.seata.codec.protobuf.generated.ResultCodeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      resultCode_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+     */
+    public Builder clearResultCode() {
+      
+      resultCode_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object msg_ = "";
+    /**
+     * <code>string msg = 3;</code>
+     */
+    public java.lang.String getMsg() {
+      java.lang.Object ref = msg_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        msg_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string msg = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getMsgBytes() {
+      java.lang.Object ref = msg_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        msg_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string msg = 3;</code>
+     */
+    public Builder setMsg(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      msg_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string msg = 3;</code>
+     */
+    public Builder clearMsg() {
+      
+      msg_ = getDefaultInstance().getMsg();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string msg = 3;</code>
+     */
+    public Builder setMsgBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      msg_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractResultMessageProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractResultMessageProto)
+  private static final io.seata.codec.protobuf.generated.AbstractResultMessageProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractResultMessageProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractResultMessageProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractResultMessageProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractResultMessageProto>() {
+    @java.lang.Override
+    public AbstractResultMessageProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractResultMessageProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractResultMessageProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractResultMessageProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractResultMessageProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..f607cfca7736255e8e5ef8ba18dab1abf8829648
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractResultMessageProtoOrBuilder.java
@@ -0,0 +1,41 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractResultMessageProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractResultMessageProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  boolean hasAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto AbstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+   */
+  int getResultCodeValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.ResultCodeProto resultCode = 2;</code>
+   */
+  io.seata.codec.protobuf.generated.ResultCodeProto getResultCode();
+
+  /**
+   * <code>string msg = 3;</code>
+   */
+  java.lang.String getMsg();
+  /**
+   * <code>string msg = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getMsgBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..932a204db6a12ab385948a3e621c3522d6adf700
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractTransactionRequest {
+  private AbstractTransactionRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n abstractTransactionRequest.proto\022\032io.s" +
+      "eata.protocol.protobuf\032\025abstractMessage." +
+      "proto\"l\n\037AbstractTransactionRequestProto" +
+      "\022I\n\017abstractMessage\030\001 \001(\01320.io.seata.pro" +
+      "tocol.protobuf.AbstractMessageProtoBA\n!i" +
+      "o.seata.codec.protobuf.generatedB\032Abstra" +
+      "ctTransactionRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor,
+        new java.lang.String[] { "AbstractMessage", });
+    io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..d66418757a317d8f6086f82cb343c8c01719afde
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractTransactionRequestProto}
+ */
+public  final class AbstractTransactionRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractTransactionRequestProto)
+    AbstractTransactionRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractTransactionRequestProto.newBuilder() to construct.
+  private AbstractTransactionRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractTransactionRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractTransactionRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractMessageProto.Builder subBuilder = null;
+            if (abstractMessage_ != null) {
+              subBuilder = abstractMessage_.toBuilder();
+            }
+            abstractMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractMessage_);
+              abstractMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractTransactionRequest.internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractTransactionRequest.internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.class, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public boolean hasAbstractMessage() {
+    return abstractMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+    return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+    return getAbstractMessage();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractMessage_ != null) {
+      output.writeMessage(1, getAbstractMessage());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractMessage());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractTransactionRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractTransactionRequestProto other = (io.seata.codec.protobuf.generated.AbstractTransactionRequestProto) obj;
+
+    if (hasAbstractMessage() != other.hasAbstractMessage()) return false;
+    if (hasAbstractMessage()) {
+      if (!getAbstractMessage()
+          .equals(other.getAbstractMessage())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractMessage()) {
+      hash = (37 * hash) + ABSTRACTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractMessage().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractTransactionRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractTransactionRequestProto)
+      io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionRequest.internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionRequest.internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.class, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionRequest.internal_static_io_seata_protocol_protobuf_AbstractTransactionRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto build() {
+      io.seata.codec.protobuf.generated.AbstractTransactionRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractTransactionRequestProto result = new io.seata.codec.protobuf.generated.AbstractTransactionRequestProto(this);
+      if (abstractMessageBuilder_ == null) {
+        result.abstractMessage_ = abstractMessage_;
+      } else {
+        result.abstractMessage_ = abstractMessageBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractTransactionRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractTransactionRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractMessage()) {
+        mergeAbstractMessage(other.getAbstractMessage());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractTransactionRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractTransactionRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> abstractMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public boolean hasAbstractMessage() {
+      return abstractMessageBuilder_ != null || abstractMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      } else {
+        return abstractMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractMessage_ = value;
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(
+        io.seata.codec.protobuf.generated.AbstractMessageProto.Builder builderForValue) {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder mergeAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (abstractMessage_ != null) {
+          abstractMessage_ =
+            io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder(abstractMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder clearAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+        onChanged();
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto.Builder getAbstractMessageBuilder() {
+      
+      onChanged();
+      return getAbstractMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+      if (abstractMessageBuilder_ != null) {
+        return abstractMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> 
+        getAbstractMessageFieldBuilder() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder>(
+                getAbstractMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractMessage_ = null;
+      }
+      return abstractMessageBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractTransactionRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractTransactionRequestProto)
+  private static final io.seata.codec.protobuf.generated.AbstractTransactionRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractTransactionRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractTransactionRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractTransactionRequestProto>() {
+    @java.lang.Override
+    public AbstractTransactionRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractTransactionRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractTransactionRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractTransactionRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..0aabafaa5506d2a18a4f0cd2f048116716e47021
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractTransactionRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractTransactionRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  boolean hasAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..c57e5ebba1df787ac5a3983943784b1c0c4c866d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponse.java
@@ -0,0 +1,68 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class AbstractTransactionResponse {
+  private AbstractTransactionResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n!abstractTransactionResponse.proto\022\032io." +
+      "seata.protocol.protobuf\032\033abstractResultM" +
+      "essage.proto\032\036transactionExceptionCode.p" +
+      "roto\"\326\001\n AbstractTransactionResponseProt" +
+      "o\022U\n\025abstractResultMessage\030\001 \001(\01326.io.se" +
+      "ata.protocol.protobuf.AbstractResultMess" +
+      "ageProto\022[\n\030transactionExceptionCode\030\002 \001" +
+      "(\01629.io.seata.protocol.protobuf.Transact" +
+      "ionExceptionCodeProtoBB\n!io.seata.codec." +
+      "protobuf.generatedB\033AbstractTransactionR" +
+      "esponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractResultMessage.getDescriptor(),
+          io.seata.codec.protobuf.generated.TransactionExceptionCode.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor,
+        new java.lang.String[] { "AbstractResultMessage", "TransactionExceptionCode", });
+    io.seata.codec.protobuf.generated.AbstractResultMessage.getDescriptor();
+    io.seata.codec.protobuf.generated.TransactionExceptionCode.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..808ea002c3e74067d32e92e444052f1144b6910c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProto.java
@@ -0,0 +1,687 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.AbstractTransactionResponseProto}
+ */
+public  final class AbstractTransactionResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.AbstractTransactionResponseProto)
+    AbstractTransactionResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use AbstractTransactionResponseProto.newBuilder() to construct.
+  private AbstractTransactionResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private AbstractTransactionResponseProto() {
+    transactionExceptionCode_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private AbstractTransactionResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder subBuilder = null;
+            if (abstractResultMessage_ != null) {
+              subBuilder = abstractResultMessage_.toBuilder();
+            }
+            abstractResultMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractResultMessage_);
+              abstractResultMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+            int rawValue = input.readEnum();
+
+            transactionExceptionCode_ = rawValue;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.AbstractTransactionResponse.internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.AbstractTransactionResponse.internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.class, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTRESULTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractResultMessageProto abstractResultMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public boolean hasAbstractResultMessage() {
+    return abstractResultMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage() {
+    return abstractResultMessage_ == null ? io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder() {
+    return getAbstractResultMessage();
+  }
+
+  public static final int TRANSACTIONEXCEPTIONCODE_FIELD_NUMBER = 2;
+  private int transactionExceptionCode_;
+  /**
+   * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+   */
+  public int getTransactionExceptionCodeValue() {
+    return transactionExceptionCode_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+   */
+  public io.seata.codec.protobuf.generated.TransactionExceptionCodeProto getTransactionExceptionCode() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.TransactionExceptionCodeProto result = io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.valueOf(transactionExceptionCode_);
+    return result == null ? io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.UNRECOGNIZED : result;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractResultMessage_ != null) {
+      output.writeMessage(1, getAbstractResultMessage());
+    }
+    if (transactionExceptionCode_ != io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.Unknown.getNumber()) {
+      output.writeEnum(2, transactionExceptionCode_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractResultMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractResultMessage());
+    }
+    if (transactionExceptionCode_ != io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.Unknown.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(2, transactionExceptionCode_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.AbstractTransactionResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.AbstractTransactionResponseProto other = (io.seata.codec.protobuf.generated.AbstractTransactionResponseProto) obj;
+
+    if (hasAbstractResultMessage() != other.hasAbstractResultMessage()) return false;
+    if (hasAbstractResultMessage()) {
+      if (!getAbstractResultMessage()
+          .equals(other.getAbstractResultMessage())) return false;
+    }
+    if (transactionExceptionCode_ != other.transactionExceptionCode_) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractResultMessage()) {
+      hash = (37 * hash) + ABSTRACTRESULTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractResultMessage().hashCode();
+    }
+    hash = (37 * hash) + TRANSACTIONEXCEPTIONCODE_FIELD_NUMBER;
+    hash = (53 * hash) + transactionExceptionCode_;
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.AbstractTransactionResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.AbstractTransactionResponseProto)
+      io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionResponse.internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionResponse.internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.class, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = null;
+      } else {
+        abstractResultMessage_ = null;
+        abstractResultMessageBuilder_ = null;
+      }
+      transactionExceptionCode_ = 0;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionResponse.internal_static_io_seata_protocol_protobuf_AbstractTransactionResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto build() {
+      io.seata.codec.protobuf.generated.AbstractTransactionResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.AbstractTransactionResponseProto result = new io.seata.codec.protobuf.generated.AbstractTransactionResponseProto(this);
+      if (abstractResultMessageBuilder_ == null) {
+        result.abstractResultMessage_ = abstractResultMessage_;
+      } else {
+        result.abstractResultMessage_ = abstractResultMessageBuilder_.build();
+      }
+      result.transactionExceptionCode_ = transactionExceptionCode_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.AbstractTransactionResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.AbstractTransactionResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractResultMessage()) {
+        mergeAbstractResultMessage(other.getAbstractResultMessage());
+      }
+      if (other.transactionExceptionCode_ != 0) {
+        setTransactionExceptionCodeValue(other.getTransactionExceptionCodeValue());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.AbstractTransactionResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.AbstractTransactionResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractResultMessageProto abstractResultMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder> abstractResultMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public boolean hasAbstractResultMessage() {
+      return abstractResultMessageBuilder_ != null || abstractResultMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage() {
+      if (abstractResultMessageBuilder_ == null) {
+        return abstractResultMessage_ == null ? io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+      } else {
+        return abstractResultMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder setAbstractResultMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto value) {
+      if (abstractResultMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractResultMessage_ = value;
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder setAbstractResultMessage(
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder builderForValue) {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder mergeAbstractResultMessage(io.seata.codec.protobuf.generated.AbstractResultMessageProto value) {
+      if (abstractResultMessageBuilder_ == null) {
+        if (abstractResultMessage_ != null) {
+          abstractResultMessage_ =
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.newBuilder(abstractResultMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractResultMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractResultMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public Builder clearAbstractResultMessage() {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessage_ = null;
+        onChanged();
+      } else {
+        abstractResultMessage_ = null;
+        abstractResultMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder getAbstractResultMessageBuilder() {
+      
+      onChanged();
+      return getAbstractResultMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder() {
+      if (abstractResultMessageBuilder_ != null) {
+        return abstractResultMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractResultMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto.getDefaultInstance() : abstractResultMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder> 
+        getAbstractResultMessageFieldBuilder() {
+      if (abstractResultMessageBuilder_ == null) {
+        abstractResultMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractResultMessageProto, io.seata.codec.protobuf.generated.AbstractResultMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder>(
+                getAbstractResultMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractResultMessage_ = null;
+      }
+      return abstractResultMessageBuilder_;
+    }
+
+    private int transactionExceptionCode_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+     */
+    public int getTransactionExceptionCodeValue() {
+      return transactionExceptionCode_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+     */
+    public Builder setTransactionExceptionCodeValue(int value) {
+      transactionExceptionCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+     */
+    public io.seata.codec.protobuf.generated.TransactionExceptionCodeProto getTransactionExceptionCode() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.TransactionExceptionCodeProto result = io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.valueOf(transactionExceptionCode_);
+      return result == null ? io.seata.codec.protobuf.generated.TransactionExceptionCodeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+     */
+    public Builder setTransactionExceptionCode(io.seata.codec.protobuf.generated.TransactionExceptionCodeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      transactionExceptionCode_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+     */
+    public Builder clearTransactionExceptionCode() {
+      
+      transactionExceptionCode_ = 0;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.AbstractTransactionResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.AbstractTransactionResponseProto)
+  private static final io.seata.codec.protobuf.generated.AbstractTransactionResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.AbstractTransactionResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<AbstractTransactionResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<AbstractTransactionResponseProto>() {
+    @java.lang.Override
+    public AbstractTransactionResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new AbstractTransactionResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<AbstractTransactionResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<AbstractTransactionResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..e51ae83631503bd902e639376b3aa9da5bf85cef
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/AbstractTransactionResponseProtoOrBuilder.java
@@ -0,0 +1,31 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: abstractTransactionResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface AbstractTransactionResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.AbstractTransactionResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  boolean hasAbstractResultMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractResultMessageProto getAbstractResultMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractResultMessageProto abstractResultMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractResultMessageProtoOrBuilder getAbstractResultMessageOrBuilder();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+   */
+  int getTransactionExceptionCodeValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.TransactionExceptionCodeProto transactionExceptionCode = 2;</code>
+   */
+  io.seata.codec.protobuf.generated.TransactionExceptionCodeProto getTransactionExceptionCode();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9397498ede06267583d839f016f6e9fec34926e7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchCommitRequest {
+  private BranchCommitRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031branchCommitRequest.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032\036abstractBranchEndReques" +
+      "t.proto\"w\n\030BranchCommitRequestProto\022[\n\030a" +
+      "bstractBranchEndRequest\030\001 \001(\01329.io.seata" +
+      ".protocol.protobuf.AbstractBranchEndRequ" +
+      "estProtoB:\n!io.seata.codec.protobuf.gene" +
+      "ratedB\023BranchCommitRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractBranchEndRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor,
+        new java.lang.String[] { "AbstractBranchEndRequest", });
+    io.seata.codec.protobuf.generated.AbstractBranchEndRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..4319a2c4dd465361d359ce1d55d1c11eeb6ee84c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchCommitRequestProto}
+ */
+public  final class BranchCommitRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchCommitRequestProto)
+    BranchCommitRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchCommitRequestProto.newBuilder() to construct.
+  private BranchCommitRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchCommitRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchCommitRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder subBuilder = null;
+            if (abstractBranchEndRequest_ != null) {
+              subBuilder = abstractBranchEndRequest_.toBuilder();
+            }
+            abstractBranchEndRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractBranchEndRequest_);
+              abstractBranchEndRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchCommitRequest.internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchCommitRequest.internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchCommitRequestProto.class, io.seata.codec.protobuf.generated.BranchCommitRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTBRANCHENDREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto abstractBranchEndRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public boolean hasAbstractBranchEndRequest() {
+    return abstractBranchEndRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest() {
+    return abstractBranchEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder() {
+    return getAbstractBranchEndRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractBranchEndRequest_ != null) {
+      output.writeMessage(1, getAbstractBranchEndRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractBranchEndRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractBranchEndRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchCommitRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchCommitRequestProto other = (io.seata.codec.protobuf.generated.BranchCommitRequestProto) obj;
+
+    if (hasAbstractBranchEndRequest() != other.hasAbstractBranchEndRequest()) return false;
+    if (hasAbstractBranchEndRequest()) {
+      if (!getAbstractBranchEndRequest()
+          .equals(other.getAbstractBranchEndRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractBranchEndRequest()) {
+      hash = (37 * hash) + ABSTRACTBRANCHENDREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractBranchEndRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchCommitRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchCommitRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchCommitRequestProto)
+      io.seata.codec.protobuf.generated.BranchCommitRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchCommitRequest.internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchCommitRequest.internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchCommitRequestProto.class, io.seata.codec.protobuf.generated.BranchCommitRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchCommitRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = null;
+      } else {
+        abstractBranchEndRequest_ = null;
+        abstractBranchEndRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchCommitRequest.internal_static_io_seata_protocol_protobuf_BranchCommitRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchCommitRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitRequestProto build() {
+      io.seata.codec.protobuf.generated.BranchCommitRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchCommitRequestProto result = new io.seata.codec.protobuf.generated.BranchCommitRequestProto(this);
+      if (abstractBranchEndRequestBuilder_ == null) {
+        result.abstractBranchEndRequest_ = abstractBranchEndRequest_;
+      } else {
+        result.abstractBranchEndRequest_ = abstractBranchEndRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchCommitRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchCommitRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchCommitRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchCommitRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractBranchEndRequest()) {
+        mergeAbstractBranchEndRequest(other.getAbstractBranchEndRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchCommitRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchCommitRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto abstractBranchEndRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder> abstractBranchEndRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public boolean hasAbstractBranchEndRequest() {
+      return abstractBranchEndRequestBuilder_ != null || abstractBranchEndRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        return abstractBranchEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+      } else {
+        return abstractBranchEndRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder setAbstractBranchEndRequest(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto value) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractBranchEndRequest_ = value;
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder setAbstractBranchEndRequest(
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder builderForValue) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder mergeAbstractBranchEndRequest(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto value) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        if (abstractBranchEndRequest_ != null) {
+          abstractBranchEndRequest_ =
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.newBuilder(abstractBranchEndRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractBranchEndRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder clearAbstractBranchEndRequest() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = null;
+        onChanged();
+      } else {
+        abstractBranchEndRequest_ = null;
+        abstractBranchEndRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder getAbstractBranchEndRequestBuilder() {
+      
+      onChanged();
+      return getAbstractBranchEndRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder() {
+      if (abstractBranchEndRequestBuilder_ != null) {
+        return abstractBranchEndRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractBranchEndRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder> 
+        getAbstractBranchEndRequestFieldBuilder() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder>(
+                getAbstractBranchEndRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractBranchEndRequest_ = null;
+      }
+      return abstractBranchEndRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchCommitRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchCommitRequestProto)
+  private static final io.seata.codec.protobuf.generated.BranchCommitRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchCommitRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchCommitRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchCommitRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchCommitRequestProto>() {
+    @java.lang.Override
+    public BranchCommitRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchCommitRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchCommitRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchCommitRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchCommitRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..572e698dd55742a481e3c31cebacc199d90a66e4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchCommitRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchCommitRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  boolean hasAbstractBranchEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..e928d5dd06738c8dc7aa69d4ba41d04d832dcdcc
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchCommitResponse {
+  private BranchCommitResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032branchCommitResponse.proto\022\032io.seata.p" +
+      "rotocol.protobuf\032\037abstractBranchEndRespo" +
+      "nse.proto\"z\n\031BranchCommitResponseProto\022]" +
+      "\n\031abstractBranchEndResponse\030\001 \001(\0132:.io.s" +
+      "eata.protocol.protobuf.AbstractBranchEnd" +
+      "ResponseProtoB;\n!io.seata.codec.protobuf" +
+      ".generatedB\024BranchCommitResponseP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractBranchEndResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor,
+        new java.lang.String[] { "AbstractBranchEndResponse", });
+    io.seata.codec.protobuf.generated.AbstractBranchEndResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e284666228696d3fec36933d7d4f8fa888d2152e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchCommitResponseProto}
+ */
+public  final class BranchCommitResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchCommitResponseProto)
+    BranchCommitResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchCommitResponseProto.newBuilder() to construct.
+  private BranchCommitResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchCommitResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchCommitResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder subBuilder = null;
+            if (abstractBranchEndResponse_ != null) {
+              subBuilder = abstractBranchEndResponse_.toBuilder();
+            }
+            abstractBranchEndResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractBranchEndResponse_);
+              abstractBranchEndResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchCommitResponse.internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchCommitResponse.internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchCommitResponseProto.class, io.seata.codec.protobuf.generated.BranchCommitResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTBRANCHENDRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto abstractBranchEndResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public boolean hasAbstractBranchEndResponse() {
+    return abstractBranchEndResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse() {
+    return abstractBranchEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder() {
+    return getAbstractBranchEndResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractBranchEndResponse_ != null) {
+      output.writeMessage(1, getAbstractBranchEndResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractBranchEndResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractBranchEndResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchCommitResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchCommitResponseProto other = (io.seata.codec.protobuf.generated.BranchCommitResponseProto) obj;
+
+    if (hasAbstractBranchEndResponse() != other.hasAbstractBranchEndResponse()) return false;
+    if (hasAbstractBranchEndResponse()) {
+      if (!getAbstractBranchEndResponse()
+          .equals(other.getAbstractBranchEndResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractBranchEndResponse()) {
+      hash = (37 * hash) + ABSTRACTBRANCHENDRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractBranchEndResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchCommitResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchCommitResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchCommitResponseProto)
+      io.seata.codec.protobuf.generated.BranchCommitResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchCommitResponse.internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchCommitResponse.internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchCommitResponseProto.class, io.seata.codec.protobuf.generated.BranchCommitResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchCommitResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = null;
+      } else {
+        abstractBranchEndResponse_ = null;
+        abstractBranchEndResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchCommitResponse.internal_static_io_seata_protocol_protobuf_BranchCommitResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchCommitResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitResponseProto build() {
+      io.seata.codec.protobuf.generated.BranchCommitResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchCommitResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchCommitResponseProto result = new io.seata.codec.protobuf.generated.BranchCommitResponseProto(this);
+      if (abstractBranchEndResponseBuilder_ == null) {
+        result.abstractBranchEndResponse_ = abstractBranchEndResponse_;
+      } else {
+        result.abstractBranchEndResponse_ = abstractBranchEndResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchCommitResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchCommitResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchCommitResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchCommitResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractBranchEndResponse()) {
+        mergeAbstractBranchEndResponse(other.getAbstractBranchEndResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchCommitResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchCommitResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto abstractBranchEndResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder> abstractBranchEndResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public boolean hasAbstractBranchEndResponse() {
+      return abstractBranchEndResponseBuilder_ != null || abstractBranchEndResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        return abstractBranchEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+      } else {
+        return abstractBranchEndResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder setAbstractBranchEndResponse(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto value) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractBranchEndResponse_ = value;
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder setAbstractBranchEndResponse(
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder builderForValue) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder mergeAbstractBranchEndResponse(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto value) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        if (abstractBranchEndResponse_ != null) {
+          abstractBranchEndResponse_ =
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.newBuilder(abstractBranchEndResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractBranchEndResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder clearAbstractBranchEndResponse() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = null;
+        onChanged();
+      } else {
+        abstractBranchEndResponse_ = null;
+        abstractBranchEndResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder getAbstractBranchEndResponseBuilder() {
+      
+      onChanged();
+      return getAbstractBranchEndResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder() {
+      if (abstractBranchEndResponseBuilder_ != null) {
+        return abstractBranchEndResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractBranchEndResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder> 
+        getAbstractBranchEndResponseFieldBuilder() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder>(
+                getAbstractBranchEndResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractBranchEndResponse_ = null;
+      }
+      return abstractBranchEndResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchCommitResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchCommitResponseProto)
+  private static final io.seata.codec.protobuf.generated.BranchCommitResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchCommitResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchCommitResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchCommitResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchCommitResponseProto>() {
+    @java.lang.Override
+    public BranchCommitResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchCommitResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchCommitResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchCommitResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchCommitResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..55a2d005699319514330c1fbee2d6e7dd44802ef
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchCommitResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchCommitResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchCommitResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  boolean hasAbstractBranchEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9cb4d7d81f64ca1103c4d648468742f2cd296545
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequest.java
@@ -0,0 +1,69 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchRegisterRequest {
+  private BranchRegisterRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\033branchRegisterRequest.proto\022\032io.seata." +
+      "protocol.protobuf\032\020branchType.proto\032 abs" +
+      "tractTransactionRequest.proto\"\211\002\n\032Branch" +
+      "RegisterRequestProto\022_\n\032abstractTransact" +
+      "ionRequest\030\001 \001(\0132;.io.seata.protocol.pro" +
+      "tobuf.AbstractTransactionRequestProto\022\013\n" +
+      "\003xid\030\002 \001(\t\022?\n\nbranchType\030\003 \001(\0162+.io.seat" +
+      "a.protocol.protobuf.BranchTypeProto\022\022\n\nr" +
+      "esourceId\030\004 \001(\t\022\017\n\007lockKey\030\005 \001(\t\022\027\n\017appl" +
+      "icationData\030\006 \001(\tB<\n!io.seata.codec.prot" +
+      "obuf.generatedB\025BranchRegisterRequestP\001b" +
+      "\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.BranchType.getDescriptor(),
+          io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionRequest", "Xid", "BranchType", "ResourceId", "LockKey", "ApplicationData", });
+    io.seata.codec.protobuf.generated.BranchType.getDescriptor();
+    io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..c2c4eaddba152b5855c1a21f1753c353b0a8ae5b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProto.java
@@ -0,0 +1,1195 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchRegisterRequestProto}
+ */
+public  final class BranchRegisterRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchRegisterRequestProto)
+    BranchRegisterRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchRegisterRequestProto.newBuilder() to construct.
+  private BranchRegisterRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchRegisterRequestProto() {
+    xid_ = "";
+    branchType_ = 0;
+    resourceId_ = "";
+    lockKey_ = "";
+    applicationData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchRegisterRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder subBuilder = null;
+            if (abstractTransactionRequest_ != null) {
+              subBuilder = abstractTransactionRequest_.toBuilder();
+            }
+            abstractTransactionRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionRequest_);
+              abstractTransactionRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 24: {
+            int rawValue = input.readEnum();
+
+            branchType_ = rawValue;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            resourceId_ = s;
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            lockKey_ = s;
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            applicationData_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchRegisterRequest.internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchRegisterRequest.internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchRegisterRequestProto.class, io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public boolean hasAbstractTransactionRequest() {
+    return abstractTransactionRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+    return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+    return getAbstractTransactionRequest();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int BRANCHTYPE_FIELD_NUMBER = 3;
+  private int branchType_;
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+   */
+  public int getBranchTypeValue() {
+    return branchType_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+    return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+  }
+
+  public static final int RESOURCEID_FIELD_NUMBER = 4;
+  private volatile java.lang.Object resourceId_;
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  public java.lang.String getResourceId() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      resourceId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  public com.google.protobuf.ByteString
+      getResourceIdBytes() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      resourceId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int LOCKKEY_FIELD_NUMBER = 5;
+  private volatile java.lang.Object lockKey_;
+  /**
+   * <code>string lockKey = 5;</code>
+   */
+  public java.lang.String getLockKey() {
+    java.lang.Object ref = lockKey_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      lockKey_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string lockKey = 5;</code>
+   */
+  public com.google.protobuf.ByteString
+      getLockKeyBytes() {
+    java.lang.Object ref = lockKey_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      lockKey_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int APPLICATIONDATA_FIELD_NUMBER = 6;
+  private volatile java.lang.Object applicationData_;
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  public java.lang.String getApplicationData() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      applicationData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  public com.google.protobuf.ByteString
+      getApplicationDataBytes() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      applicationData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionRequest_ != null) {
+      output.writeMessage(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      output.writeEnum(3, branchType_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, resourceId_);
+    }
+    if (!getLockKeyBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, lockKey_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, applicationData_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(3, branchType_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, resourceId_);
+    }
+    if (!getLockKeyBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, lockKey_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, applicationData_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchRegisterRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchRegisterRequestProto other = (io.seata.codec.protobuf.generated.BranchRegisterRequestProto) obj;
+
+    if (hasAbstractTransactionRequest() != other.hasAbstractTransactionRequest()) return false;
+    if (hasAbstractTransactionRequest()) {
+      if (!getAbstractTransactionRequest()
+          .equals(other.getAbstractTransactionRequest())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (branchType_ != other.branchType_) return false;
+    if (!getResourceId()
+        .equals(other.getResourceId())) return false;
+    if (!getLockKey()
+        .equals(other.getLockKey())) return false;
+    if (!getApplicationData()
+        .equals(other.getApplicationData())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionRequest()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionRequest().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + BRANCHTYPE_FIELD_NUMBER;
+    hash = (53 * hash) + branchType_;
+    hash = (37 * hash) + RESOURCEID_FIELD_NUMBER;
+    hash = (53 * hash) + getResourceId().hashCode();
+    hash = (37 * hash) + LOCKKEY_FIELD_NUMBER;
+    hash = (53 * hash) + getLockKey().hashCode();
+    hash = (37 * hash) + APPLICATIONDATA_FIELD_NUMBER;
+    hash = (53 * hash) + getApplicationData().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchRegisterRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchRegisterRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchRegisterRequestProto)
+      io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchRegisterRequest.internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchRegisterRequest.internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchRegisterRequestProto.class, io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchRegisterRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+      xid_ = "";
+
+      branchType_ = 0;
+
+      resourceId_ = "";
+
+      lockKey_ = "";
+
+      applicationData_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchRegisterRequest.internal_static_io_seata_protocol_protobuf_BranchRegisterRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchRegisterRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProto build() {
+      io.seata.codec.protobuf.generated.BranchRegisterRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchRegisterRequestProto result = new io.seata.codec.protobuf.generated.BranchRegisterRequestProto(this);
+      if (abstractTransactionRequestBuilder_ == null) {
+        result.abstractTransactionRequest_ = abstractTransactionRequest_;
+      } else {
+        result.abstractTransactionRequest_ = abstractTransactionRequestBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.branchType_ = branchType_;
+      result.resourceId_ = resourceId_;
+      result.lockKey_ = lockKey_;
+      result.applicationData_ = applicationData_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchRegisterRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchRegisterRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchRegisterRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchRegisterRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionRequest()) {
+        mergeAbstractTransactionRequest(other.getAbstractTransactionRequest());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (other.branchType_ != 0) {
+        setBranchTypeValue(other.getBranchTypeValue());
+      }
+      if (!other.getResourceId().isEmpty()) {
+        resourceId_ = other.resourceId_;
+        onChanged();
+      }
+      if (!other.getLockKey().isEmpty()) {
+        lockKey_ = other.lockKey_;
+        onChanged();
+      }
+      if (!other.getApplicationData().isEmpty()) {
+        applicationData_ = other.applicationData_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchRegisterRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchRegisterRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> abstractTransactionRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public boolean hasAbstractTransactionRequest() {
+      return abstractTransactionRequestBuilder_ != null || abstractTransactionRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      } else {
+        return abstractTransactionRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionRequest_ = value;
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder builderForValue) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder mergeAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (abstractTransactionRequest_ != null) {
+          abstractTransactionRequest_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder(abstractTransactionRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder clearAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+        onChanged();
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder getAbstractTransactionRequestBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+      if (abstractTransactionRequestBuilder_ != null) {
+        return abstractTransactionRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> 
+        getAbstractTransactionRequestFieldBuilder() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder>(
+                getAbstractTransactionRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionRequest_ = null;
+      }
+      return abstractTransactionRequestBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int branchType_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+     */
+    public int getBranchTypeValue() {
+      return branchType_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+     */
+    public Builder setBranchTypeValue(int value) {
+      branchType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+      return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+     */
+    public Builder setBranchType(io.seata.codec.protobuf.generated.BranchTypeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      branchType_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+     */
+    public Builder clearBranchType() {
+      
+      branchType_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object resourceId_ = "";
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public java.lang.String getResourceId() {
+      java.lang.Object ref = resourceId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        resourceId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getResourceIdBytes() {
+      java.lang.Object ref = resourceId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        resourceId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder setResourceId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder clearResourceId() {
+      
+      resourceId_ = getDefaultInstance().getResourceId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder setResourceIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object lockKey_ = "";
+    /**
+     * <code>string lockKey = 5;</code>
+     */
+    public java.lang.String getLockKey() {
+      java.lang.Object ref = lockKey_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        lockKey_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string lockKey = 5;</code>
+     */
+    public com.google.protobuf.ByteString
+        getLockKeyBytes() {
+      java.lang.Object ref = lockKey_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        lockKey_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string lockKey = 5;</code>
+     */
+    public Builder setLockKey(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      lockKey_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string lockKey = 5;</code>
+     */
+    public Builder clearLockKey() {
+      
+      lockKey_ = getDefaultInstance().getLockKey();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string lockKey = 5;</code>
+     */
+    public Builder setLockKeyBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      lockKey_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object applicationData_ = "";
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public java.lang.String getApplicationData() {
+      java.lang.Object ref = applicationData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        applicationData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getApplicationDataBytes() {
+      java.lang.Object ref = applicationData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        applicationData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder clearApplicationData() {
+      
+      applicationData_ = getDefaultInstance().getApplicationData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchRegisterRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchRegisterRequestProto)
+  private static final io.seata.codec.protobuf.generated.BranchRegisterRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchRegisterRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRegisterRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchRegisterRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchRegisterRequestProto>() {
+    @java.lang.Override
+    public BranchRegisterRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchRegisterRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchRegisterRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchRegisterRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchRegisterRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d55b7d3a0eaa525052995662b44b51339ab8a78
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterRequestProtoOrBuilder.java
@@ -0,0 +1,71 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchRegisterRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchRegisterRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  boolean hasAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+   */
+  int getBranchTypeValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 3;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchTypeProto getBranchType();
+
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  java.lang.String getResourceId();
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  com.google.protobuf.ByteString
+      getResourceIdBytes();
+
+  /**
+   * <code>string lockKey = 5;</code>
+   */
+  java.lang.String getLockKey();
+  /**
+   * <code>string lockKey = 5;</code>
+   */
+  com.google.protobuf.ByteString
+      getLockKeyBytes();
+
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  java.lang.String getApplicationData();
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  com.google.protobuf.ByteString
+      getApplicationDataBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..aceb49945c27132ca6fcd6ee35dcc7c6094513fa
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchRegisterResponse {
+  private BranchRegisterResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\034branchRegisterResponse.proto\022\032io.seata" +
+      ".protocol.protobuf\032!abstractTransactionR" +
+      "esponse.proto\"\222\001\n\033BranchRegisterResponse" +
+      "Proto\022a\n\033abstractTransactionResponse\030\001 \001" +
+      "(\0132<.io.seata.protocol.protobuf.Abstract" +
+      "TransactionResponseProto\022\020\n\010branchId\030\002 \001" +
+      "(\003B=\n!io.seata.codec.protobuf.generatedB" +
+      "\026BranchRegisterResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", "BranchId", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c3658e9fe067ece243254ef7c28c02fb3eb874b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProto.java
@@ -0,0 +1,660 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchRegisterResponseProto}
+ */
+public  final class BranchRegisterResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchRegisterResponseProto)
+    BranchRegisterResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchRegisterResponseProto.newBuilder() to construct.
+  private BranchRegisterResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchRegisterResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchRegisterResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+
+            branchId_ = input.readInt64();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchRegisterResponse.internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchRegisterResponse.internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchRegisterResponseProto.class, io.seata.codec.protobuf.generated.BranchRegisterResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  public static final int BRANCHID_FIELD_NUMBER = 2;
+  private long branchId_;
+  /**
+   * <code>int64 branchId = 2;</code>
+   */
+  public long getBranchId() {
+    return branchId_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    if (branchId_ != 0L) {
+      output.writeInt64(2, branchId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    if (branchId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(2, branchId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchRegisterResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchRegisterResponseProto other = (io.seata.codec.protobuf.generated.BranchRegisterResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (getBranchId()
+        != other.getBranchId()) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (37 * hash) + BRANCHID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getBranchId());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchRegisterResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchRegisterResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchRegisterResponseProto)
+      io.seata.codec.protobuf.generated.BranchRegisterResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchRegisterResponse.internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchRegisterResponse.internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchRegisterResponseProto.class, io.seata.codec.protobuf.generated.BranchRegisterResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchRegisterResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      branchId_ = 0L;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchRegisterResponse.internal_static_io_seata_protocol_protobuf_BranchRegisterResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchRegisterResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterResponseProto build() {
+      io.seata.codec.protobuf.generated.BranchRegisterResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRegisterResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchRegisterResponseProto result = new io.seata.codec.protobuf.generated.BranchRegisterResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      result.branchId_ = branchId_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchRegisterResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchRegisterResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchRegisterResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchRegisterResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      if (other.getBranchId() != 0L) {
+        setBranchId(other.getBranchId());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchRegisterResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchRegisterResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+
+    private long branchId_ ;
+    /**
+     * <code>int64 branchId = 2;</code>
+     */
+    public long getBranchId() {
+      return branchId_;
+    }
+    /**
+     * <code>int64 branchId = 2;</code>
+     */
+    public Builder setBranchId(long value) {
+      
+      branchId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 branchId = 2;</code>
+     */
+    public Builder clearBranchId() {
+      
+      branchId_ = 0L;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchRegisterResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchRegisterResponseProto)
+  private static final io.seata.codec.protobuf.generated.BranchRegisterResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchRegisterResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRegisterResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchRegisterResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchRegisterResponseProto>() {
+    @java.lang.Override
+    public BranchRegisterResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchRegisterResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchRegisterResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchRegisterResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchRegisterResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..eaa4328313d59257a18e913432ac330fa9493791
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRegisterResponseProtoOrBuilder.java
@@ -0,0 +1,27 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRegisterResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchRegisterResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchRegisterResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+
+  /**
+   * <code>int64 branchId = 2;</code>
+   */
+  long getBranchId();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b31fa92f9c3baf1e8ee41177df5f60826a88487
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequest.java
@@ -0,0 +1,73 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchReportRequest {
+  private BranchReportRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031branchReportRequest.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032\022branchStatus.proto\032\020bra" +
+      "nchType.proto\032 abstractTransactionReques" +
+      "t.proto\"\307\002\n\030BranchReportRequestProto\022_\n\032" +
+      "abstractTransactionRequest\030\001 \001(\0132;.io.se" +
+      "ata.protocol.protobuf.AbstractTransactio" +
+      "nRequestProto\022\013\n\003xid\030\002 \001(\t\022\020\n\010branchId\030\003" +
+      " \001(\003\022\022\n\nresourceId\030\004 \001(\t\022=\n\006status\030\005 \001(\016" +
+      "2-.io.seata.protocol.protobuf.BranchStat" +
+      "usProto\022\027\n\017applicationData\030\006 \001(\t\022?\n\nbran" +
+      "chType\030\007 \001(\0162+.io.seata.protocol.protobu" +
+      "f.BranchTypeProtoB:\n!io.seata.codec.prot" +
+      "obuf.generatedB\023BranchReportRequestP\001b\006p" +
+      "roto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.BranchStatus.getDescriptor(),
+          io.seata.codec.protobuf.generated.BranchType.getDescriptor(),
+          io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionRequest", "Xid", "BranchId", "ResourceId", "Status", "ApplicationData", "BranchType", });
+    io.seata.codec.protobuf.generated.BranchStatus.getDescriptor();
+    io.seata.codec.protobuf.generated.BranchType.getDescriptor();
+    io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7475b9630c0c54215f77dc8f799ef5492c2f65f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProto.java
@@ -0,0 +1,1203 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchReportRequestProto}
+ */
+public  final class BranchReportRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchReportRequestProto)
+    BranchReportRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchReportRequestProto.newBuilder() to construct.
+  private BranchReportRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchReportRequestProto() {
+    xid_ = "";
+    resourceId_ = "";
+    status_ = 0;
+    applicationData_ = "";
+    branchType_ = 0;
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchReportRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder subBuilder = null;
+            if (abstractTransactionRequest_ != null) {
+              subBuilder = abstractTransactionRequest_.toBuilder();
+            }
+            abstractTransactionRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionRequest_);
+              abstractTransactionRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 24: {
+
+            branchId_ = input.readInt64();
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            resourceId_ = s;
+            break;
+          }
+          case 40: {
+            int rawValue = input.readEnum();
+
+            status_ = rawValue;
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            applicationData_ = s;
+            break;
+          }
+          case 56: {
+            int rawValue = input.readEnum();
+
+            branchType_ = rawValue;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchReportRequest.internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchReportRequest.internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchReportRequestProto.class, io.seata.codec.protobuf.generated.BranchReportRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public boolean hasAbstractTransactionRequest() {
+    return abstractTransactionRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+    return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+    return getAbstractTransactionRequest();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int BRANCHID_FIELD_NUMBER = 3;
+  private long branchId_;
+  /**
+   * <code>int64 branchId = 3;</code>
+   */
+  public long getBranchId() {
+    return branchId_;
+  }
+
+  public static final int RESOURCEID_FIELD_NUMBER = 4;
+  private volatile java.lang.Object resourceId_;
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  public java.lang.String getResourceId() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      resourceId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  public com.google.protobuf.ByteString
+      getResourceIdBytes() {
+    java.lang.Object ref = resourceId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      resourceId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int STATUS_FIELD_NUMBER = 5;
+  private int status_;
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+   */
+  public int getStatusValue() {
+    return status_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchStatusProto getStatus() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.BranchStatusProto result = io.seata.codec.protobuf.generated.BranchStatusProto.valueOf(status_);
+    return result == null ? io.seata.codec.protobuf.generated.BranchStatusProto.UNRECOGNIZED : result;
+  }
+
+  public static final int APPLICATIONDATA_FIELD_NUMBER = 6;
+  private volatile java.lang.Object applicationData_;
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  public java.lang.String getApplicationData() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      applicationData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  public com.google.protobuf.ByteString
+      getApplicationDataBytes() {
+    java.lang.Object ref = applicationData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      applicationData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int BRANCHTYPE_FIELD_NUMBER = 7;
+  private int branchType_;
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+   */
+  public int getBranchTypeValue() {
+    return branchType_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+    @SuppressWarnings("deprecation")
+    io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+    return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionRequest_ != null) {
+      output.writeMessage(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (branchId_ != 0L) {
+      output.writeInt64(3, branchId_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, resourceId_);
+    }
+    if (status_ != io.seata.codec.protobuf.generated.BranchStatusProto.BUnknown.getNumber()) {
+      output.writeEnum(5, status_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, applicationData_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      output.writeEnum(7, branchType_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionRequest());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (branchId_ != 0L) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt64Size(3, branchId_);
+    }
+    if (!getResourceIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, resourceId_);
+    }
+    if (status_ != io.seata.codec.protobuf.generated.BranchStatusProto.BUnknown.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(5, status_);
+    }
+    if (!getApplicationDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, applicationData_);
+    }
+    if (branchType_ != io.seata.codec.protobuf.generated.BranchTypeProto.AT.getNumber()) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeEnumSize(7, branchType_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchReportRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchReportRequestProto other = (io.seata.codec.protobuf.generated.BranchReportRequestProto) obj;
+
+    if (hasAbstractTransactionRequest() != other.hasAbstractTransactionRequest()) return false;
+    if (hasAbstractTransactionRequest()) {
+      if (!getAbstractTransactionRequest()
+          .equals(other.getAbstractTransactionRequest())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (getBranchId()
+        != other.getBranchId()) return false;
+    if (!getResourceId()
+        .equals(other.getResourceId())) return false;
+    if (status_ != other.status_) return false;
+    if (!getApplicationData()
+        .equals(other.getApplicationData())) return false;
+    if (branchType_ != other.branchType_) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionRequest()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionRequest().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + BRANCHID_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashLong(
+        getBranchId());
+    hash = (37 * hash) + RESOURCEID_FIELD_NUMBER;
+    hash = (53 * hash) + getResourceId().hashCode();
+    hash = (37 * hash) + STATUS_FIELD_NUMBER;
+    hash = (53 * hash) + status_;
+    hash = (37 * hash) + APPLICATIONDATA_FIELD_NUMBER;
+    hash = (53 * hash) + getApplicationData().hashCode();
+    hash = (37 * hash) + BRANCHTYPE_FIELD_NUMBER;
+    hash = (53 * hash) + branchType_;
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchReportRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchReportRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchReportRequestProto)
+      io.seata.codec.protobuf.generated.BranchReportRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchReportRequest.internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchReportRequest.internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchReportRequestProto.class, io.seata.codec.protobuf.generated.BranchReportRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchReportRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+      xid_ = "";
+
+      branchId_ = 0L;
+
+      resourceId_ = "";
+
+      status_ = 0;
+
+      applicationData_ = "";
+
+      branchType_ = 0;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchReportRequest.internal_static_io_seata_protocol_protobuf_BranchReportRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchReportRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportRequestProto build() {
+      io.seata.codec.protobuf.generated.BranchReportRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchReportRequestProto result = new io.seata.codec.protobuf.generated.BranchReportRequestProto(this);
+      if (abstractTransactionRequestBuilder_ == null) {
+        result.abstractTransactionRequest_ = abstractTransactionRequest_;
+      } else {
+        result.abstractTransactionRequest_ = abstractTransactionRequestBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.branchId_ = branchId_;
+      result.resourceId_ = resourceId_;
+      result.status_ = status_;
+      result.applicationData_ = applicationData_;
+      result.branchType_ = branchType_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchReportRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchReportRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchReportRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchReportRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionRequest()) {
+        mergeAbstractTransactionRequest(other.getAbstractTransactionRequest());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (other.getBranchId() != 0L) {
+        setBranchId(other.getBranchId());
+      }
+      if (!other.getResourceId().isEmpty()) {
+        resourceId_ = other.resourceId_;
+        onChanged();
+      }
+      if (other.status_ != 0) {
+        setStatusValue(other.getStatusValue());
+      }
+      if (!other.getApplicationData().isEmpty()) {
+        applicationData_ = other.applicationData_;
+        onChanged();
+      }
+      if (other.branchType_ != 0) {
+        setBranchTypeValue(other.getBranchTypeValue());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchReportRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchReportRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> abstractTransactionRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public boolean hasAbstractTransactionRequest() {
+      return abstractTransactionRequestBuilder_ != null || abstractTransactionRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      } else {
+        return abstractTransactionRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionRequest_ = value;
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder builderForValue) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder mergeAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (abstractTransactionRequest_ != null) {
+          abstractTransactionRequest_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder(abstractTransactionRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder clearAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+        onChanged();
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder getAbstractTransactionRequestBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+      if (abstractTransactionRequestBuilder_ != null) {
+        return abstractTransactionRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> 
+        getAbstractTransactionRequestFieldBuilder() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder>(
+                getAbstractTransactionRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionRequest_ = null;
+      }
+      return abstractTransactionRequestBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private long branchId_ ;
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public long getBranchId() {
+      return branchId_;
+    }
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder setBranchId(long value) {
+      
+      branchId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int64 branchId = 3;</code>
+     */
+    public Builder clearBranchId() {
+      
+      branchId_ = 0L;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object resourceId_ = "";
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public java.lang.String getResourceId() {
+      java.lang.Object ref = resourceId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        resourceId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public com.google.protobuf.ByteString
+        getResourceIdBytes() {
+      java.lang.Object ref = resourceId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        resourceId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder setResourceId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder clearResourceId() {
+      
+      resourceId_ = getDefaultInstance().getResourceId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceId = 4;</code>
+     */
+    public Builder setResourceIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      resourceId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int status_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+     */
+    public int getStatusValue() {
+      return status_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+     */
+    public Builder setStatusValue(int value) {
+      status_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchStatusProto getStatus() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.BranchStatusProto result = io.seata.codec.protobuf.generated.BranchStatusProto.valueOf(status_);
+      return result == null ? io.seata.codec.protobuf.generated.BranchStatusProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+     */
+    public Builder setStatus(io.seata.codec.protobuf.generated.BranchStatusProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      status_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+     */
+    public Builder clearStatus() {
+      
+      status_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object applicationData_ = "";
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public java.lang.String getApplicationData() {
+      java.lang.Object ref = applicationData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        applicationData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public com.google.protobuf.ByteString
+        getApplicationDataBytes() {
+      java.lang.Object ref = applicationData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        applicationData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder clearApplicationData() {
+      
+      applicationData_ = getDefaultInstance().getApplicationData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string applicationData = 6;</code>
+     */
+    public Builder setApplicationDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      applicationData_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int branchType_ = 0;
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+     */
+    public int getBranchTypeValue() {
+      return branchType_;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+     */
+    public Builder setBranchTypeValue(int value) {
+      branchType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchTypeProto getBranchType() {
+      @SuppressWarnings("deprecation")
+      io.seata.codec.protobuf.generated.BranchTypeProto result = io.seata.codec.protobuf.generated.BranchTypeProto.valueOf(branchType_);
+      return result == null ? io.seata.codec.protobuf.generated.BranchTypeProto.UNRECOGNIZED : result;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+     */
+    public Builder setBranchType(io.seata.codec.protobuf.generated.BranchTypeProto value) {
+      if (value == null) {
+        throw new NullPointerException();
+      }
+      
+      branchType_ = value.getNumber();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+     */
+    public Builder clearBranchType() {
+      
+      branchType_ = 0;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchReportRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchReportRequestProto)
+  private static final io.seata.codec.protobuf.generated.BranchReportRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchReportRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchReportRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchReportRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchReportRequestProto>() {
+    @java.lang.Override
+    public BranchReportRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchReportRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchReportRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchReportRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchReportRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..81526f8a4b16980dd43e9b5fb06ba550e1960596
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportRequestProtoOrBuilder.java
@@ -0,0 +1,75 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchReportRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchReportRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  boolean hasAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <code>int64 branchId = 3;</code>
+   */
+  long getBranchId();
+
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  java.lang.String getResourceId();
+  /**
+   * <code>string resourceId = 4;</code>
+   */
+  com.google.protobuf.ByteString
+      getResourceIdBytes();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+   */
+  int getStatusValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchStatusProto status = 5;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchStatusProto getStatus();
+
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  java.lang.String getApplicationData();
+  /**
+   * <code>string applicationData = 6;</code>
+   */
+  com.google.protobuf.ByteString
+      getApplicationDataBytes();
+
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+   */
+  int getBranchTypeValue();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchTypeProto branchType = 7;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchTypeProto getBranchType();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..07562d3fe46c551f4cd10c79a87e7173ee15a520
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchReportResponse {
+  private BranchReportResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032branchReportResponse.proto\022\032io.seata.p" +
+      "rotocol.protobuf\032!abstractTransactionRes" +
+      "ponse.proto\"~\n\031BranchReportResponseProto" +
+      "\022a\n\033abstractTransactionResponse\030\001 \001(\0132<." +
+      "io.seata.protocol.protobuf.AbstractTrans" +
+      "actionResponseProtoB;\n!io.seata.codec.pr" +
+      "otobuf.generatedB\024BranchReportResponseP\001" +
+      "b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a8dbb3752d207d326453ca793c22a0413aff643
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchReportResponseProto}
+ */
+public  final class BranchReportResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchReportResponseProto)
+    BranchReportResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchReportResponseProto.newBuilder() to construct.
+  private BranchReportResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchReportResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchReportResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchReportResponse.internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchReportResponse.internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchReportResponseProto.class, io.seata.codec.protobuf.generated.BranchReportResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchReportResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchReportResponseProto other = (io.seata.codec.protobuf.generated.BranchReportResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchReportResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchReportResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchReportResponseProto)
+      io.seata.codec.protobuf.generated.BranchReportResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchReportResponse.internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchReportResponse.internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchReportResponseProto.class, io.seata.codec.protobuf.generated.BranchReportResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchReportResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchReportResponse.internal_static_io_seata_protocol_protobuf_BranchReportResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchReportResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportResponseProto build() {
+      io.seata.codec.protobuf.generated.BranchReportResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchReportResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchReportResponseProto result = new io.seata.codec.protobuf.generated.BranchReportResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchReportResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchReportResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchReportResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchReportResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchReportResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchReportResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchReportResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchReportResponseProto)
+  private static final io.seata.codec.protobuf.generated.BranchReportResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchReportResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchReportResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchReportResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchReportResponseProto>() {
+    @java.lang.Override
+    public BranchReportResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchReportResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchReportResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchReportResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchReportResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..09412aab969726f14952164a1bc54d9bf063b1cd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchReportResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchReportResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchReportResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchReportResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffc71fdd0568bde3df4d1e0c0d4623b7480891f6
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequest.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchRollbackRequest {
+  private BranchRollbackRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\033branchRollbackRequest.proto\022\032io.seata." +
+      "protocol.protobuf\032\036abstractBranchEndRequ" +
+      "est.proto\"y\n\032BranchRollbackRequestProto\022" +
+      "[\n\030abstractBranchEndRequest\030\001 \001(\01329.io.s" +
+      "eata.protocol.protobuf.AbstractBranchEnd" +
+      "RequestProtoB<\n!io.seata.codec.protobuf." +
+      "generatedB\025BranchRollbackRequestP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractBranchEndRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor,
+        new java.lang.String[] { "AbstractBranchEndRequest", });
+    io.seata.codec.protobuf.generated.AbstractBranchEndRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a66d306844c2bd3a673dc84a2a1d724fb07d0d7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchRollbackRequestProto}
+ */
+public  final class BranchRollbackRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchRollbackRequestProto)
+    BranchRollbackRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchRollbackRequestProto.newBuilder() to construct.
+  private BranchRollbackRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchRollbackRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchRollbackRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder subBuilder = null;
+            if (abstractBranchEndRequest_ != null) {
+              subBuilder = abstractBranchEndRequest_.toBuilder();
+            }
+            abstractBranchEndRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractBranchEndRequest_);
+              abstractBranchEndRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchRollbackRequest.internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchRollbackRequest.internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchRollbackRequestProto.class, io.seata.codec.protobuf.generated.BranchRollbackRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTBRANCHENDREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto abstractBranchEndRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public boolean hasAbstractBranchEndRequest() {
+    return abstractBranchEndRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest() {
+    return abstractBranchEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder() {
+    return getAbstractBranchEndRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractBranchEndRequest_ != null) {
+      output.writeMessage(1, getAbstractBranchEndRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractBranchEndRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractBranchEndRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchRollbackRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchRollbackRequestProto other = (io.seata.codec.protobuf.generated.BranchRollbackRequestProto) obj;
+
+    if (hasAbstractBranchEndRequest() != other.hasAbstractBranchEndRequest()) return false;
+    if (hasAbstractBranchEndRequest()) {
+      if (!getAbstractBranchEndRequest()
+          .equals(other.getAbstractBranchEndRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractBranchEndRequest()) {
+      hash = (37 * hash) + ABSTRACTBRANCHENDREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractBranchEndRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchRollbackRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchRollbackRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchRollbackRequestProto)
+      io.seata.codec.protobuf.generated.BranchRollbackRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchRollbackRequest.internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchRollbackRequest.internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchRollbackRequestProto.class, io.seata.codec.protobuf.generated.BranchRollbackRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchRollbackRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = null;
+      } else {
+        abstractBranchEndRequest_ = null;
+        abstractBranchEndRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchRollbackRequest.internal_static_io_seata_protocol_protobuf_BranchRollbackRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchRollbackRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackRequestProto build() {
+      io.seata.codec.protobuf.generated.BranchRollbackRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchRollbackRequestProto result = new io.seata.codec.protobuf.generated.BranchRollbackRequestProto(this);
+      if (abstractBranchEndRequestBuilder_ == null) {
+        result.abstractBranchEndRequest_ = abstractBranchEndRequest_;
+      } else {
+        result.abstractBranchEndRequest_ = abstractBranchEndRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchRollbackRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchRollbackRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchRollbackRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchRollbackRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractBranchEndRequest()) {
+        mergeAbstractBranchEndRequest(other.getAbstractBranchEndRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchRollbackRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchRollbackRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto abstractBranchEndRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder> abstractBranchEndRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public boolean hasAbstractBranchEndRequest() {
+      return abstractBranchEndRequestBuilder_ != null || abstractBranchEndRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        return abstractBranchEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+      } else {
+        return abstractBranchEndRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder setAbstractBranchEndRequest(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto value) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractBranchEndRequest_ = value;
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder setAbstractBranchEndRequest(
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder builderForValue) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder mergeAbstractBranchEndRequest(io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto value) {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        if (abstractBranchEndRequest_ != null) {
+          abstractBranchEndRequest_ =
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.newBuilder(abstractBranchEndRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractBranchEndRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractBranchEndRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public Builder clearAbstractBranchEndRequest() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequest_ = null;
+        onChanged();
+      } else {
+        abstractBranchEndRequest_ = null;
+        abstractBranchEndRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder getAbstractBranchEndRequestBuilder() {
+      
+      onChanged();
+      return getAbstractBranchEndRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder() {
+      if (abstractBranchEndRequestBuilder_ != null) {
+        return abstractBranchEndRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractBranchEndRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.getDefaultInstance() : abstractBranchEndRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder> 
+        getAbstractBranchEndRequestFieldBuilder() {
+      if (abstractBranchEndRequestBuilder_ == null) {
+        abstractBranchEndRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder>(
+                getAbstractBranchEndRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractBranchEndRequest_ = null;
+      }
+      return abstractBranchEndRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchRollbackRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchRollbackRequestProto)
+  private static final io.seata.codec.protobuf.generated.BranchRollbackRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchRollbackRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRollbackRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchRollbackRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchRollbackRequestProto>() {
+    @java.lang.Override
+    public BranchRollbackRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchRollbackRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchRollbackRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchRollbackRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchRollbackRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..969274078a8624baafe15223193443f3ab172f9a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchRollbackRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchRollbackRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  boolean hasAbstractBranchEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndRequestProto getAbstractBranchEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndRequestProto abstractBranchEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndRequestProtoOrBuilder getAbstractBranchEndRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..66b04b0abed1a59f23345287f26eb65562709d4d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchRollbackResponse {
+  private BranchRollbackResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\034branchRollbackResponse.proto\022\032io.seata" +
+      ".protocol.protobuf\032\037abstractBranchEndRes" +
+      "ponse.proto\"|\n\033BranchRollbackResponsePro" +
+      "to\022]\n\031abstractBranchEndResponse\030\001 \001(\0132:." +
+      "io.seata.protocol.protobuf.AbstractBranc" +
+      "hEndResponseProtoB=\n!io.seata.codec.prot" +
+      "obuf.generatedB\026BranchRollbackResponseP\001" +
+      "b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractBranchEndResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor,
+        new java.lang.String[] { "AbstractBranchEndResponse", });
+    io.seata.codec.protobuf.generated.AbstractBranchEndResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..50dd87d787cd112bd56b60d3967c67e8d8b36ca9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.BranchRollbackResponseProto}
+ */
+public  final class BranchRollbackResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.BranchRollbackResponseProto)
+    BranchRollbackResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use BranchRollbackResponseProto.newBuilder() to construct.
+  private BranchRollbackResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private BranchRollbackResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private BranchRollbackResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder subBuilder = null;
+            if (abstractBranchEndResponse_ != null) {
+              subBuilder = abstractBranchEndResponse_.toBuilder();
+            }
+            abstractBranchEndResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractBranchEndResponse_);
+              abstractBranchEndResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchRollbackResponse.internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.BranchRollbackResponse.internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.BranchRollbackResponseProto.class, io.seata.codec.protobuf.generated.BranchRollbackResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTBRANCHENDRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto abstractBranchEndResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public boolean hasAbstractBranchEndResponse() {
+    return abstractBranchEndResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse() {
+    return abstractBranchEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder() {
+    return getAbstractBranchEndResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractBranchEndResponse_ != null) {
+      output.writeMessage(1, getAbstractBranchEndResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractBranchEndResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractBranchEndResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.BranchRollbackResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.BranchRollbackResponseProto other = (io.seata.codec.protobuf.generated.BranchRollbackResponseProto) obj;
+
+    if (hasAbstractBranchEndResponse() != other.hasAbstractBranchEndResponse()) return false;
+    if (hasAbstractBranchEndResponse()) {
+      if (!getAbstractBranchEndResponse()
+          .equals(other.getAbstractBranchEndResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractBranchEndResponse()) {
+      hash = (37 * hash) + ABSTRACTBRANCHENDRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractBranchEndResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.BranchRollbackResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.BranchRollbackResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.BranchRollbackResponseProto)
+      io.seata.codec.protobuf.generated.BranchRollbackResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.BranchRollbackResponse.internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.BranchRollbackResponse.internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.BranchRollbackResponseProto.class, io.seata.codec.protobuf.generated.BranchRollbackResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.BranchRollbackResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = null;
+      } else {
+        abstractBranchEndResponse_ = null;
+        abstractBranchEndResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.BranchRollbackResponse.internal_static_io_seata_protocol_protobuf_BranchRollbackResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.BranchRollbackResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackResponseProto build() {
+      io.seata.codec.protobuf.generated.BranchRollbackResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.BranchRollbackResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.BranchRollbackResponseProto result = new io.seata.codec.protobuf.generated.BranchRollbackResponseProto(this);
+      if (abstractBranchEndResponseBuilder_ == null) {
+        result.abstractBranchEndResponse_ = abstractBranchEndResponse_;
+      } else {
+        result.abstractBranchEndResponse_ = abstractBranchEndResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.BranchRollbackResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.BranchRollbackResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.BranchRollbackResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.BranchRollbackResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractBranchEndResponse()) {
+        mergeAbstractBranchEndResponse(other.getAbstractBranchEndResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.BranchRollbackResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.BranchRollbackResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto abstractBranchEndResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder> abstractBranchEndResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public boolean hasAbstractBranchEndResponse() {
+      return abstractBranchEndResponseBuilder_ != null || abstractBranchEndResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        return abstractBranchEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+      } else {
+        return abstractBranchEndResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder setAbstractBranchEndResponse(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto value) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractBranchEndResponse_ = value;
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder setAbstractBranchEndResponse(
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder builderForValue) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder mergeAbstractBranchEndResponse(io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto value) {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        if (abstractBranchEndResponse_ != null) {
+          abstractBranchEndResponse_ =
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.newBuilder(abstractBranchEndResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractBranchEndResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractBranchEndResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public Builder clearAbstractBranchEndResponse() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponse_ = null;
+        onChanged();
+      } else {
+        abstractBranchEndResponse_ = null;
+        abstractBranchEndResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder getAbstractBranchEndResponseBuilder() {
+      
+      onChanged();
+      return getAbstractBranchEndResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder() {
+      if (abstractBranchEndResponseBuilder_ != null) {
+        return abstractBranchEndResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractBranchEndResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.getDefaultInstance() : abstractBranchEndResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder> 
+        getAbstractBranchEndResponseFieldBuilder() {
+      if (abstractBranchEndResponseBuilder_ == null) {
+        abstractBranchEndResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder>(
+                getAbstractBranchEndResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractBranchEndResponse_ = null;
+      }
+      return abstractBranchEndResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.BranchRollbackResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.BranchRollbackResponseProto)
+  private static final io.seata.codec.protobuf.generated.BranchRollbackResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.BranchRollbackResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.BranchRollbackResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<BranchRollbackResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<BranchRollbackResponseProto>() {
+    @java.lang.Override
+    public BranchRollbackResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new BranchRollbackResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<BranchRollbackResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<BranchRollbackResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.BranchRollbackResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..25e5fffa507c23a81af519bd0b53b81e8ce8b7fe
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchRollbackResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface BranchRollbackResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.BranchRollbackResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  boolean hasAbstractBranchEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndResponseProto getAbstractBranchEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractBranchEndResponseProto abstractBranchEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractBranchEndResponseProtoOrBuilder getAbstractBranchEndResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatus.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..29d9d2b0c4115c28d5a2ec27e2f78dacbdf9ecc2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatus.java
@@ -0,0 +1,53 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchStatus.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchStatus {
+  private BranchStatus() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\022branchStatus.proto\022\032io.seata.protocol." +
+      "protobuf*\274\002\n\021BranchStatusProto\022\014\n\010BUnkno" +
+      "wn\020\000\022\016\n\nRegistered\020\001\022\021\n\rPhaseOne_Done\020\002\022" +
+      "\023\n\017PhaseOne_Failed\020\003\022\024\n\020PhaseOne_Timeout" +
+      "\020\004\022\026\n\022PhaseTwo_Committed\020\005\022#\n\037PhaseTwo_C" +
+      "ommitFailed_Retryable\020\006\022%\n!PhaseTwo_Comm" +
+      "itFailed_Unretryable\020\007\022\027\n\023PhaseTwo_Rollb" +
+      "acked\020\010\022%\n!PhaseTwo_RollbackFailed_Retry" +
+      "able\020\t\022\'\n#PhaseTwo_RollbackFailed_Unretr" +
+      "yable\020\nB3\n!io.seata.codec.protobuf.gener" +
+      "atedB\014BranchStatusP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatusProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatusProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac5bd9422ac8b68b208dc06ff6bde16e98188cbd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchStatusProto.java
@@ -0,0 +1,276 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchStatus.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.BranchStatusProto}
+ */
+public enum BranchStatusProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <pre>
+   * special for Unknown
+   * </pre>
+   *
+   * <code>BUnknown = 0;</code>
+   */
+  BUnknown(0),
+  /**
+   * <pre>
+   * Registered to TC.
+   * </pre>
+   *
+   * <code>Registered = 1;</code>
+   */
+  Registered(1),
+  /**
+   * <pre>
+   * Branch logic is successfully done at phase one.
+   * </pre>
+   *
+   * <code>PhaseOne_Done = 2;</code>
+   */
+  PhaseOne_Done(2),
+  /**
+   * <pre>
+   * Branch logic is failed at phase one.
+   * </pre>
+   *
+   * <code>PhaseOne_Failed = 3;</code>
+   */
+  PhaseOne_Failed(3),
+  /**
+   * <pre>
+   * Branch logic is NOT reported for a timeout.
+   * </pre>
+   *
+   * <code>PhaseOne_Timeout = 4;</code>
+   */
+  PhaseOne_Timeout(4),
+  /**
+   * <pre>
+   * Commit logic is successfully done at phase two.
+   * </pre>
+   *
+   * <code>PhaseTwo_Committed = 5;</code>
+   */
+  PhaseTwo_Committed(5),
+  /**
+   * <pre>
+   * Commit logic is failed but retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_CommitFailed_Retryable = 6;</code>
+   */
+  PhaseTwo_CommitFailed_Retryable(6),
+  /**
+   * <pre>
+   * Commit logic is failed and NOT retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_CommitFailed_Unretryable = 7;</code>
+   */
+  PhaseTwo_CommitFailed_Unretryable(7),
+  /**
+   * <pre>
+   * Rollback logic is successfully done at phase two.
+   * </pre>
+   *
+   * <code>PhaseTwo_Rollbacked = 8;</code>
+   */
+  PhaseTwo_Rollbacked(8),
+  /**
+   * <pre>
+   * Rollback logic is failed but retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_RollbackFailed_Retryable = 9;</code>
+   */
+  PhaseTwo_RollbackFailed_Retryable(9),
+  /**
+   * <pre>
+   * Rollback logic is failed but NOT retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_RollbackFailed_Unretryable = 10;</code>
+   */
+  PhaseTwo_RollbackFailed_Unretryable(10),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <pre>
+   * special for Unknown
+   * </pre>
+   *
+   * <code>BUnknown = 0;</code>
+   */
+  public static final int BUnknown_VALUE = 0;
+  /**
+   * <pre>
+   * Registered to TC.
+   * </pre>
+   *
+   * <code>Registered = 1;</code>
+   */
+  public static final int Registered_VALUE = 1;
+  /**
+   * <pre>
+   * Branch logic is successfully done at phase one.
+   * </pre>
+   *
+   * <code>PhaseOne_Done = 2;</code>
+   */
+  public static final int PhaseOne_Done_VALUE = 2;
+  /**
+   * <pre>
+   * Branch logic is failed at phase one.
+   * </pre>
+   *
+   * <code>PhaseOne_Failed = 3;</code>
+   */
+  public static final int PhaseOne_Failed_VALUE = 3;
+  /**
+   * <pre>
+   * Branch logic is NOT reported for a timeout.
+   * </pre>
+   *
+   * <code>PhaseOne_Timeout = 4;</code>
+   */
+  public static final int PhaseOne_Timeout_VALUE = 4;
+  /**
+   * <pre>
+   * Commit logic is successfully done at phase two.
+   * </pre>
+   *
+   * <code>PhaseTwo_Committed = 5;</code>
+   */
+  public static final int PhaseTwo_Committed_VALUE = 5;
+  /**
+   * <pre>
+   * Commit logic is failed but retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_CommitFailed_Retryable = 6;</code>
+   */
+  public static final int PhaseTwo_CommitFailed_Retryable_VALUE = 6;
+  /**
+   * <pre>
+   * Commit logic is failed and NOT retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_CommitFailed_Unretryable = 7;</code>
+   */
+  public static final int PhaseTwo_CommitFailed_Unretryable_VALUE = 7;
+  /**
+   * <pre>
+   * Rollback logic is successfully done at phase two.
+   * </pre>
+   *
+   * <code>PhaseTwo_Rollbacked = 8;</code>
+   */
+  public static final int PhaseTwo_Rollbacked_VALUE = 8;
+  /**
+   * <pre>
+   * Rollback logic is failed but retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_RollbackFailed_Retryable = 9;</code>
+   */
+  public static final int PhaseTwo_RollbackFailed_Retryable_VALUE = 9;
+  /**
+   * <pre>
+   * Rollback logic is failed but NOT retryable.
+   * </pre>
+   *
+   * <code>PhaseTwo_RollbackFailed_Unretryable = 10;</code>
+   */
+  public static final int PhaseTwo_RollbackFailed_Unretryable_VALUE = 10;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static BranchStatusProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static BranchStatusProto forNumber(int value) {
+    switch (value) {
+      case 0: return BUnknown;
+      case 1: return Registered;
+      case 2: return PhaseOne_Done;
+      case 3: return PhaseOne_Failed;
+      case 4: return PhaseOne_Timeout;
+      case 5: return PhaseTwo_Committed;
+      case 6: return PhaseTwo_CommitFailed_Retryable;
+      case 7: return PhaseTwo_CommitFailed_Unretryable;
+      case 8: return PhaseTwo_Rollbacked;
+      case 9: return PhaseTwo_RollbackFailed_Retryable;
+      case 10: return PhaseTwo_RollbackFailed_Unretryable;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<BranchStatusProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      BranchStatusProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<BranchStatusProto>() {
+          public BranchStatusProto findValueByNumber(int number) {
+            return BranchStatusProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchStatus.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final BranchStatusProto[] VALUES = values();
+
+  public static BranchStatusProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private BranchStatusProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.BranchStatusProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchType.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchType.java
new file mode 100644
index 0000000000000000000000000000000000000000..5779ccaab5388b1c2cbe7ddb15ebbbe74675e906
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchType.java
@@ -0,0 +1,46 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchType.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class BranchType {
+  private BranchType() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020branchType.proto\022\032io.seata.protocol.pr" +
+      "otobuf*\"\n\017BranchTypeProto\022\006\n\002AT\020\000\022\007\n\003TCC" +
+      "\020\001B1\n!io.seata.codec.protobuf.generatedB" +
+      "\nBranchTypeP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchTypeProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchTypeProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..03f36e3f7a5320679e8c864f3daedc8902f7a969
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/BranchTypeProto.java
@@ -0,0 +1,107 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: branchType.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.BranchTypeProto}
+ */
+public enum BranchTypeProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <code>AT = 0;</code>
+   */
+  AT(0),
+  /**
+   * <code>TCC = 1;</code>
+   */
+  TCC(1),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <code>AT = 0;</code>
+   */
+  public static final int AT_VALUE = 0;
+  /**
+   * <code>TCC = 1;</code>
+   */
+  public static final int TCC_VALUE = 1;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static BranchTypeProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static BranchTypeProto forNumber(int value) {
+    switch (value) {
+      case 0: return AT;
+      case 1: return TCC;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<BranchTypeProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      BranchTypeProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<BranchTypeProto>() {
+          public BranchTypeProto findValueByNumber(int number) {
+            return BranchTypeProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.BranchType.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final BranchTypeProto[] VALUES = values();
+
+  public static BranchTypeProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private BranchTypeProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.BranchTypeProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..19cb54e919a142f960b6db411edef9e0ff2d929a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequest.java
@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalBeginRequest {
+  private GlobalBeginRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\030globalBeginRequest.proto\022\032io.seata.pro" +
+      "tocol.protobuf\032 abstractTransactionReque" +
+      "st.proto\"\244\001\n\027GlobalBeginRequestProto\022_\n\032" +
+      "abstractTransactionRequest\030\001 \001(\0132;.io.se" +
+      "ata.protocol.protobuf.AbstractTransactio" +
+      "nRequestProto\022\017\n\007timeout\030\002 \001(\005\022\027\n\017transa" +
+      "ctionName\030\003 \001(\tB9\n!io.seata.codec.protob" +
+      "uf.generatedB\022GlobalBeginRequestP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionRequest", "Timeout", "TransactionName", });
+    io.seata.codec.protobuf.generated.AbstractTransactionRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe763c3e624a182471493c828225ab6f1adff0b4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProto.java
@@ -0,0 +1,778 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalBeginRequestProto}
+ */
+public  final class GlobalBeginRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalBeginRequestProto)
+    GlobalBeginRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalBeginRequestProto.newBuilder() to construct.
+  private GlobalBeginRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalBeginRequestProto() {
+    transactionName_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalBeginRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder subBuilder = null;
+            if (abstractTransactionRequest_ != null) {
+              subBuilder = abstractTransactionRequest_.toBuilder();
+            }
+            abstractTransactionRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionRequest_);
+              abstractTransactionRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+
+            timeout_ = input.readInt32();
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            transactionName_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalBeginRequest.internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalBeginRequest.internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalBeginRequestProto.class, io.seata.codec.protobuf.generated.GlobalBeginRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public boolean hasAbstractTransactionRequest() {
+    return abstractTransactionRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+    return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+    return getAbstractTransactionRequest();
+  }
+
+  public static final int TIMEOUT_FIELD_NUMBER = 2;
+  private int timeout_;
+  /**
+   * <code>int32 timeout = 2;</code>
+   */
+  public int getTimeout() {
+    return timeout_;
+  }
+
+  public static final int TRANSACTIONNAME_FIELD_NUMBER = 3;
+  private volatile java.lang.Object transactionName_;
+  /**
+   * <code>string transactionName = 3;</code>
+   */
+  public java.lang.String getTransactionName() {
+    java.lang.Object ref = transactionName_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      transactionName_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string transactionName = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getTransactionNameBytes() {
+    java.lang.Object ref = transactionName_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      transactionName_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionRequest_ != null) {
+      output.writeMessage(1, getAbstractTransactionRequest());
+    }
+    if (timeout_ != 0) {
+      output.writeInt32(2, timeout_);
+    }
+    if (!getTransactionNameBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, transactionName_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionRequest());
+    }
+    if (timeout_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(2, timeout_);
+    }
+    if (!getTransactionNameBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, transactionName_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalBeginRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalBeginRequestProto other = (io.seata.codec.protobuf.generated.GlobalBeginRequestProto) obj;
+
+    if (hasAbstractTransactionRequest() != other.hasAbstractTransactionRequest()) return false;
+    if (hasAbstractTransactionRequest()) {
+      if (!getAbstractTransactionRequest()
+          .equals(other.getAbstractTransactionRequest())) return false;
+    }
+    if (getTimeout()
+        != other.getTimeout()) return false;
+    if (!getTransactionName()
+        .equals(other.getTransactionName())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionRequest()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionRequest().hashCode();
+    }
+    hash = (37 * hash) + TIMEOUT_FIELD_NUMBER;
+    hash = (53 * hash) + getTimeout();
+    hash = (37 * hash) + TRANSACTIONNAME_FIELD_NUMBER;
+    hash = (53 * hash) + getTransactionName().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalBeginRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalBeginRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalBeginRequestProto)
+      io.seata.codec.protobuf.generated.GlobalBeginRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalBeginRequest.internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalBeginRequest.internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalBeginRequestProto.class, io.seata.codec.protobuf.generated.GlobalBeginRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalBeginRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+      timeout_ = 0;
+
+      transactionName_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalBeginRequest.internal_static_io_seata_protocol_protobuf_GlobalBeginRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalBeginRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginRequestProto build() {
+      io.seata.codec.protobuf.generated.GlobalBeginRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalBeginRequestProto result = new io.seata.codec.protobuf.generated.GlobalBeginRequestProto(this);
+      if (abstractTransactionRequestBuilder_ == null) {
+        result.abstractTransactionRequest_ = abstractTransactionRequest_;
+      } else {
+        result.abstractTransactionRequest_ = abstractTransactionRequestBuilder_.build();
+      }
+      result.timeout_ = timeout_;
+      result.transactionName_ = transactionName_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalBeginRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalBeginRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalBeginRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalBeginRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionRequest()) {
+        mergeAbstractTransactionRequest(other.getAbstractTransactionRequest());
+      }
+      if (other.getTimeout() != 0) {
+        setTimeout(other.getTimeout());
+      }
+      if (!other.getTransactionName().isEmpty()) {
+        transactionName_ = other.transactionName_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalBeginRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalBeginRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionRequestProto abstractTransactionRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> abstractTransactionRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public boolean hasAbstractTransactionRequest() {
+      return abstractTransactionRequestBuilder_ != null || abstractTransactionRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        return abstractTransactionRequest_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      } else {
+        return abstractTransactionRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionRequest_ = value;
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder setAbstractTransactionRequest(
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder builderForValue) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder mergeAbstractTransactionRequest(io.seata.codec.protobuf.generated.AbstractTransactionRequestProto value) {
+      if (abstractTransactionRequestBuilder_ == null) {
+        if (abstractTransactionRequest_ != null) {
+          abstractTransactionRequest_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.newBuilder(abstractTransactionRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public Builder clearAbstractTransactionRequest() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequest_ = null;
+        onChanged();
+      } else {
+        abstractTransactionRequest_ = null;
+        abstractTransactionRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder getAbstractTransactionRequestBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder() {
+      if (abstractTransactionRequestBuilder_ != null) {
+        return abstractTransactionRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.getDefaultInstance() : abstractTransactionRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder> 
+        getAbstractTransactionRequestFieldBuilder() {
+      if (abstractTransactionRequestBuilder_ == null) {
+        abstractTransactionRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionRequestProto, io.seata.codec.protobuf.generated.AbstractTransactionRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder>(
+                getAbstractTransactionRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionRequest_ = null;
+      }
+      return abstractTransactionRequestBuilder_;
+    }
+
+    private int timeout_ ;
+    /**
+     * <code>int32 timeout = 2;</code>
+     */
+    public int getTimeout() {
+      return timeout_;
+    }
+    /**
+     * <code>int32 timeout = 2;</code>
+     */
+    public Builder setTimeout(int value) {
+      
+      timeout_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>int32 timeout = 2;</code>
+     */
+    public Builder clearTimeout() {
+      
+      timeout_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object transactionName_ = "";
+    /**
+     * <code>string transactionName = 3;</code>
+     */
+    public java.lang.String getTransactionName() {
+      java.lang.Object ref = transactionName_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        transactionName_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string transactionName = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getTransactionNameBytes() {
+      java.lang.Object ref = transactionName_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        transactionName_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string transactionName = 3;</code>
+     */
+    public Builder setTransactionName(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      transactionName_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string transactionName = 3;</code>
+     */
+    public Builder clearTransactionName() {
+      
+      transactionName_ = getDefaultInstance().getTransactionName();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string transactionName = 3;</code>
+     */
+    public Builder setTransactionNameBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      transactionName_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalBeginRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalBeginRequestProto)
+  private static final io.seata.codec.protobuf.generated.GlobalBeginRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalBeginRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalBeginRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalBeginRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalBeginRequestProto>() {
+    @java.lang.Override
+    public GlobalBeginRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalBeginRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalBeginRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalBeginRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalBeginRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..59b1c1c054917f8085735ac888e7c7f4156feda0
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginRequestProtoOrBuilder.java
@@ -0,0 +1,37 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalBeginRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalBeginRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  boolean hasAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProto getAbstractTransactionRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionRequestProto abstractTransactionRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionRequestProtoOrBuilder getAbstractTransactionRequestOrBuilder();
+
+  /**
+   * <code>int32 timeout = 2;</code>
+   */
+  int getTimeout();
+
+  /**
+   * <code>string transactionName = 3;</code>
+   */
+  java.lang.String getTransactionName();
+  /**
+   * <code>string transactionName = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getTransactionNameBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..2b6130643c64aa6d1a31e07725ad4f24acd6d694
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalBeginResponse {
+  private GlobalBeginResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031globalBeginResponse.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032!abstractTransactionResp" +
+      "onse.proto\"\235\001\n\030GlobalBeginResponseProto\022" +
+      "a\n\033abstractTransactionResponse\030\001 \001(\0132<.i" +
+      "o.seata.protocol.protobuf.AbstractTransa" +
+      "ctionResponseProto\022\013\n\003xid\030\002 \001(\t\022\021\n\textra" +
+      "Data\030\003 \001(\tB:\n!io.seata.codec.protobuf.ge" +
+      "neratedB\023GlobalBeginResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", "Xid", "ExtraData", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d949102a0b494cb93c66f68ab79e773c1f13cf7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProto.java
@@ -0,0 +1,848 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalBeginResponseProto}
+ */
+public  final class GlobalBeginResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalBeginResponseProto)
+    GlobalBeginResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalBeginResponseProto.newBuilder() to construct.
+  private GlobalBeginResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalBeginResponseProto() {
+    xid_ = "";
+    extraData_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalBeginResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            xid_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            extraData_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalBeginResponse.internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalBeginResponse.internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalBeginResponseProto.class, io.seata.codec.protobuf.generated.GlobalBeginResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  public static final int XID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object xid_;
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public java.lang.String getXid() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      xid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string xid = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getXidBytes() {
+    java.lang.Object ref = xid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      xid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int EXTRADATA_FIELD_NUMBER = 3;
+  private volatile java.lang.Object extraData_;
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public java.lang.String getExtraData() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      extraData_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  public com.google.protobuf.ByteString
+      getExtraDataBytes() {
+    java.lang.Object ref = extraData_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      extraData_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    if (!getXidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, xid_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, extraData_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    if (!getXidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, xid_);
+    }
+    if (!getExtraDataBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, extraData_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalBeginResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalBeginResponseProto other = (io.seata.codec.protobuf.generated.GlobalBeginResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (!getXid()
+        .equals(other.getXid())) return false;
+    if (!getExtraData()
+        .equals(other.getExtraData())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (37 * hash) + XID_FIELD_NUMBER;
+    hash = (53 * hash) + getXid().hashCode();
+    hash = (37 * hash) + EXTRADATA_FIELD_NUMBER;
+    hash = (53 * hash) + getExtraData().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalBeginResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalBeginResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalBeginResponseProto)
+      io.seata.codec.protobuf.generated.GlobalBeginResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalBeginResponse.internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalBeginResponse.internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalBeginResponseProto.class, io.seata.codec.protobuf.generated.GlobalBeginResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalBeginResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      xid_ = "";
+
+      extraData_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalBeginResponse.internal_static_io_seata_protocol_protobuf_GlobalBeginResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalBeginResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginResponseProto build() {
+      io.seata.codec.protobuf.generated.GlobalBeginResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalBeginResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalBeginResponseProto result = new io.seata.codec.protobuf.generated.GlobalBeginResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      result.xid_ = xid_;
+      result.extraData_ = extraData_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalBeginResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalBeginResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalBeginResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalBeginResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      if (!other.getXid().isEmpty()) {
+        xid_ = other.xid_;
+        onChanged();
+      }
+      if (!other.getExtraData().isEmpty()) {
+        extraData_ = other.extraData_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalBeginResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalBeginResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+
+    private java.lang.Object xid_ = "";
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public java.lang.String getXid() {
+      java.lang.Object ref = xid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        xid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getXidBytes() {
+      java.lang.Object ref = xid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        xid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder clearXid() {
+      
+      xid_ = getDefaultInstance().getXid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string xid = 2;</code>
+     */
+    public Builder setXidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      xid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object extraData_ = "";
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public java.lang.String getExtraData() {
+      java.lang.Object ref = extraData_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        extraData_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public com.google.protobuf.ByteString
+        getExtraDataBytes() {
+      java.lang.Object ref = extraData_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        extraData_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraData(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder clearExtraData() {
+      
+      extraData_ = getDefaultInstance().getExtraData();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string extraData = 3;</code>
+     */
+    public Builder setExtraDataBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      extraData_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalBeginResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalBeginResponseProto)
+  private static final io.seata.codec.protobuf.generated.GlobalBeginResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalBeginResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalBeginResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalBeginResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalBeginResponseProto>() {
+    @java.lang.Override
+    public GlobalBeginResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalBeginResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalBeginResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalBeginResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalBeginResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..621147f00d4d9b92553023e4ff20ac88846ef008
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalBeginResponseProtoOrBuilder.java
@@ -0,0 +1,42 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalBeginResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalBeginResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalBeginResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+
+  /**
+   * <code>string xid = 2;</code>
+   */
+  java.lang.String getXid();
+  /**
+   * <code>string xid = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getXidBytes();
+
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  java.lang.String getExtraData();
+  /**
+   * <code>string extraData = 3;</code>
+   */
+  com.google.protobuf.ByteString
+      getExtraDataBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..49a94816a92094acba6477925fc37d49ec69fcf4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalCommitRequest {
+  private GlobalCommitRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031globalCommitRequest.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032\036abstractGlobalEndReques" +
+      "t.proto\"w\n\030GlobalCommitRequestProto\022[\n\030a" +
+      "bstractGlobalEndRequest\030\001 \001(\01329.io.seata" +
+      ".protocol.protobuf.AbstractGlobalEndRequ" +
+      "estProtoB:\n!io.seata.codec.protobuf.gene" +
+      "ratedB\023GlobalCommitRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndRequest", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..804e082bf1ac2dc92789389e1604a2b60d47700e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalCommitRequestProto}
+ */
+public  final class GlobalCommitRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalCommitRequestProto)
+    GlobalCommitRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalCommitRequestProto.newBuilder() to construct.
+  private GlobalCommitRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalCommitRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalCommitRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder subBuilder = null;
+            if (abstractGlobalEndRequest_ != null) {
+              subBuilder = abstractGlobalEndRequest_.toBuilder();
+            }
+            abstractGlobalEndRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndRequest_);
+              abstractGlobalEndRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalCommitRequest.internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalCommitRequest.internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalCommitRequestProto.class, io.seata.codec.protobuf.generated.GlobalCommitRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+    return getAbstractGlobalEndRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndRequest_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalCommitRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalCommitRequestProto other = (io.seata.codec.protobuf.generated.GlobalCommitRequestProto) obj;
+
+    if (hasAbstractGlobalEndRequest() != other.hasAbstractGlobalEndRequest()) return false;
+    if (hasAbstractGlobalEndRequest()) {
+      if (!getAbstractGlobalEndRequest()
+          .equals(other.getAbstractGlobalEndRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndRequest()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalCommitRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalCommitRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalCommitRequestProto)
+      io.seata.codec.protobuf.generated.GlobalCommitRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalCommitRequest.internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalCommitRequest.internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalCommitRequestProto.class, io.seata.codec.protobuf.generated.GlobalCommitRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalCommitRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalCommitRequest.internal_static_io_seata_protocol_protobuf_GlobalCommitRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalCommitRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitRequestProto build() {
+      io.seata.codec.protobuf.generated.GlobalCommitRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalCommitRequestProto result = new io.seata.codec.protobuf.generated.GlobalCommitRequestProto(this);
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequest_;
+      } else {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalCommitRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalCommitRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalCommitRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalCommitRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndRequest()) {
+        mergeAbstractGlobalEndRequest(other.getAbstractGlobalEndRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalCommitRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalCommitRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> abstractGlobalEndRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndRequest() {
+      return abstractGlobalEndRequestBuilder_ != null || abstractGlobalEndRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      } else {
+        return abstractGlobalEndRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndRequest_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder builderForValue) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (abstractGlobalEndRequest_ != null) {
+          abstractGlobalEndRequest_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.newBuilder(abstractGlobalEndRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder getAbstractGlobalEndRequestBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+      if (abstractGlobalEndRequestBuilder_ != null) {
+        return abstractGlobalEndRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> 
+        getAbstractGlobalEndRequestFieldBuilder() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder>(
+                getAbstractGlobalEndRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndRequest_ = null;
+      }
+      return abstractGlobalEndRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalCommitRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalCommitRequestProto)
+  private static final io.seata.codec.protobuf.generated.GlobalCommitRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalCommitRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalCommitRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalCommitRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalCommitRequestProto>() {
+    @java.lang.Override
+    public GlobalCommitRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalCommitRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalCommitRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalCommitRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalCommitRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ecafc23e13816158038ea5f886ad6a2c90370a7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalCommitRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalCommitRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  boolean hasAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d5b343ba9529ac336520f31d923de682a677786
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalCommitResponse {
+  private GlobalCommitResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032globalCommitResponse.proto\022\032io.seata.p" +
+      "rotocol.protobuf\032\037abstractGlobalEndRespo" +
+      "nse.proto\"z\n\031GlobalCommitResponseProto\022]" +
+      "\n\031abstractGlobalEndResponse\030\001 \001(\0132:.io.s" +
+      "eata.protocol.protobuf.AbstractGlobalEnd" +
+      "ResponseProtoB;\n!io.seata.codec.protobuf" +
+      ".generatedB\024GlobalCommitResponseP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndResponse", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..4527aa37a2752d051ba15472dc3fa8170be74b4d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalCommitResponseProto}
+ */
+public  final class GlobalCommitResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalCommitResponseProto)
+    GlobalCommitResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalCommitResponseProto.newBuilder() to construct.
+  private GlobalCommitResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalCommitResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalCommitResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder subBuilder = null;
+            if (abstractGlobalEndResponse_ != null) {
+              subBuilder = abstractGlobalEndResponse_.toBuilder();
+            }
+            abstractGlobalEndResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndResponse_);
+              abstractGlobalEndResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalCommitResponse.internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalCommitResponse.internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalCommitResponseProto.class, io.seata.codec.protobuf.generated.GlobalCommitResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+    return getAbstractGlobalEndResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndResponse_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalCommitResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalCommitResponseProto other = (io.seata.codec.protobuf.generated.GlobalCommitResponseProto) obj;
+
+    if (hasAbstractGlobalEndResponse() != other.hasAbstractGlobalEndResponse()) return false;
+    if (hasAbstractGlobalEndResponse()) {
+      if (!getAbstractGlobalEndResponse()
+          .equals(other.getAbstractGlobalEndResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndResponse()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalCommitResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalCommitResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalCommitResponseProto)
+      io.seata.codec.protobuf.generated.GlobalCommitResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalCommitResponse.internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalCommitResponse.internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalCommitResponseProto.class, io.seata.codec.protobuf.generated.GlobalCommitResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalCommitResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalCommitResponse.internal_static_io_seata_protocol_protobuf_GlobalCommitResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalCommitResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitResponseProto build() {
+      io.seata.codec.protobuf.generated.GlobalCommitResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalCommitResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalCommitResponseProto result = new io.seata.codec.protobuf.generated.GlobalCommitResponseProto(this);
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponse_;
+      } else {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalCommitResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalCommitResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalCommitResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalCommitResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndResponse()) {
+        mergeAbstractGlobalEndResponse(other.getAbstractGlobalEndResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalCommitResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalCommitResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> abstractGlobalEndResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndResponse() {
+      return abstractGlobalEndResponseBuilder_ != null || abstractGlobalEndResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      } else {
+        return abstractGlobalEndResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndResponse_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder builderForValue) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (abstractGlobalEndResponse_ != null) {
+          abstractGlobalEndResponse_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.newBuilder(abstractGlobalEndResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder getAbstractGlobalEndResponseBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+      if (abstractGlobalEndResponseBuilder_ != null) {
+        return abstractGlobalEndResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> 
+        getAbstractGlobalEndResponseFieldBuilder() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder>(
+                getAbstractGlobalEndResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndResponse_ = null;
+      }
+      return abstractGlobalEndResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalCommitResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalCommitResponseProto)
+  private static final io.seata.codec.protobuf.generated.GlobalCommitResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalCommitResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalCommitResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalCommitResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalCommitResponseProto>() {
+    @java.lang.Override
+    public GlobalCommitResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalCommitResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalCommitResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalCommitResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalCommitResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..ba48e77352b5fee8cf93a1ce243d59aa547a349d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalCommitResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalCommitResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalCommitResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalCommitResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  boolean hasAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..42310a89e7afc00384886e2710809c1ad3d573df
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalLockQueryRequest {
+  private GlobalLockQueryRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\034globalLockQueryRequest.proto\022\032io.seata" +
+      ".protocol.protobuf\032\033branchRegisterReques" +
+      "t.proto\"t\n\033GlobalLockQueryRequestProto\022U" +
+      "\n\025branchRegisterRequest\030\001 \001(\01326.io.seata" +
+      ".protocol.protobuf.BranchRegisterRequest" +
+      "ProtoB=\n!io.seata.codec.protobuf.generat" +
+      "edB\026GlobalLockQueryRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.BranchRegisterRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor,
+        new java.lang.String[] { "BranchRegisterRequest", });
+    io.seata.codec.protobuf.generated.BranchRegisterRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..566d0c8c85f812c13e431b37a1745b278d94385a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalLockQueryRequestProto}
+ */
+public  final class GlobalLockQueryRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalLockQueryRequestProto)
+    GlobalLockQueryRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalLockQueryRequestProto.newBuilder() to construct.
+  private GlobalLockQueryRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalLockQueryRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalLockQueryRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder subBuilder = null;
+            if (branchRegisterRequest_ != null) {
+              subBuilder = branchRegisterRequest_.toBuilder();
+            }
+            branchRegisterRequest_ = input.readMessage(io.seata.codec.protobuf.generated.BranchRegisterRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(branchRegisterRequest_);
+              branchRegisterRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalLockQueryRequest.internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalLockQueryRequest.internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.class, io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.Builder.class);
+  }
+
+  public static final int BRANCHREGISTERREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.BranchRegisterRequestProto branchRegisterRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  public boolean hasBranchRegisterRequest() {
+    return branchRegisterRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchRegisterRequestProto getBranchRegisterRequest() {
+    return branchRegisterRequest_ == null ? io.seata.codec.protobuf.generated.BranchRegisterRequestProto.getDefaultInstance() : branchRegisterRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder getBranchRegisterRequestOrBuilder() {
+    return getBranchRegisterRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (branchRegisterRequest_ != null) {
+      output.writeMessage(1, getBranchRegisterRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (branchRegisterRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getBranchRegisterRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto other = (io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto) obj;
+
+    if (hasBranchRegisterRequest() != other.hasBranchRegisterRequest()) return false;
+    if (hasBranchRegisterRequest()) {
+      if (!getBranchRegisterRequest()
+          .equals(other.getBranchRegisterRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasBranchRegisterRequest()) {
+      hash = (37 * hash) + BRANCHREGISTERREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getBranchRegisterRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalLockQueryRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalLockQueryRequestProto)
+      io.seata.codec.protobuf.generated.GlobalLockQueryRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryRequest.internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryRequest.internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.class, io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (branchRegisterRequestBuilder_ == null) {
+        branchRegisterRequest_ = null;
+      } else {
+        branchRegisterRequest_ = null;
+        branchRegisterRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryRequest.internal_static_io_seata_protocol_protobuf_GlobalLockQueryRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto build() {
+      io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto result = new io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto(this);
+      if (branchRegisterRequestBuilder_ == null) {
+        result.branchRegisterRequest_ = branchRegisterRequest_;
+      } else {
+        result.branchRegisterRequest_ = branchRegisterRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto.getDefaultInstance()) return this;
+      if (other.hasBranchRegisterRequest()) {
+        mergeBranchRegisterRequest(other.getBranchRegisterRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.BranchRegisterRequestProto branchRegisterRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.BranchRegisterRequestProto, io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder, io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder> branchRegisterRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public boolean hasBranchRegisterRequest() {
+      return branchRegisterRequestBuilder_ != null || branchRegisterRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProto getBranchRegisterRequest() {
+      if (branchRegisterRequestBuilder_ == null) {
+        return branchRegisterRequest_ == null ? io.seata.codec.protobuf.generated.BranchRegisterRequestProto.getDefaultInstance() : branchRegisterRequest_;
+      } else {
+        return branchRegisterRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public Builder setBranchRegisterRequest(io.seata.codec.protobuf.generated.BranchRegisterRequestProto value) {
+      if (branchRegisterRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        branchRegisterRequest_ = value;
+        onChanged();
+      } else {
+        branchRegisterRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public Builder setBranchRegisterRequest(
+        io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder builderForValue) {
+      if (branchRegisterRequestBuilder_ == null) {
+        branchRegisterRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        branchRegisterRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public Builder mergeBranchRegisterRequest(io.seata.codec.protobuf.generated.BranchRegisterRequestProto value) {
+      if (branchRegisterRequestBuilder_ == null) {
+        if (branchRegisterRequest_ != null) {
+          branchRegisterRequest_ =
+            io.seata.codec.protobuf.generated.BranchRegisterRequestProto.newBuilder(branchRegisterRequest_).mergeFrom(value).buildPartial();
+        } else {
+          branchRegisterRequest_ = value;
+        }
+        onChanged();
+      } else {
+        branchRegisterRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public Builder clearBranchRegisterRequest() {
+      if (branchRegisterRequestBuilder_ == null) {
+        branchRegisterRequest_ = null;
+        onChanged();
+      } else {
+        branchRegisterRequest_ = null;
+        branchRegisterRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder getBranchRegisterRequestBuilder() {
+      
+      onChanged();
+      return getBranchRegisterRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder getBranchRegisterRequestOrBuilder() {
+      if (branchRegisterRequestBuilder_ != null) {
+        return branchRegisterRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return branchRegisterRequest_ == null ?
+            io.seata.codec.protobuf.generated.BranchRegisterRequestProto.getDefaultInstance() : branchRegisterRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.BranchRegisterRequestProto, io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder, io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder> 
+        getBranchRegisterRequestFieldBuilder() {
+      if (branchRegisterRequestBuilder_ == null) {
+        branchRegisterRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.BranchRegisterRequestProto, io.seata.codec.protobuf.generated.BranchRegisterRequestProto.Builder, io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder>(
+                getBranchRegisterRequest(),
+                getParentForChildren(),
+                isClean());
+        branchRegisterRequest_ = null;
+      }
+      return branchRegisterRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalLockQueryRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalLockQueryRequestProto)
+  private static final io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalLockQueryRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalLockQueryRequestProto>() {
+    @java.lang.Override
+    public GlobalLockQueryRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalLockQueryRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalLockQueryRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalLockQueryRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfe6689202031805314d0c7ac9a43818e15013e5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalLockQueryRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalLockQueryRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  boolean hasBranchRegisterRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchRegisterRequestProto getBranchRegisterRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.BranchRegisterRequestProto branchRegisterRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.BranchRegisterRequestProtoOrBuilder getBranchRegisterRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c0727f3dc7c3f91d4113984979e82afc7c9bbbd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalLockQueryResponse {
+  private GlobalLockQueryResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\035globalLockQueryResponse.proto\022\032io.seat" +
+      "a.protocol.protobuf\032!abstractTransaction" +
+      "Response.proto\"\223\001\n\034GlobalLockQueryRespon" +
+      "seProto\022a\n\033abstractTransactionResponse\030\001" +
+      " \001(\0132<.io.seata.protocol.protobuf.Abstra" +
+      "ctTransactionResponseProto\022\020\n\010lockable\030\002" +
+      " \001(\010B>\n!io.seata.codec.protobuf.generate" +
+      "dB\027GlobalLockQueryResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor,
+        new java.lang.String[] { "AbstractTransactionResponse", "Lockable", });
+    io.seata.codec.protobuf.generated.AbstractTransactionResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..01302f0274bb75cecb0ae7cb6590b47e8d8ecb49
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProto.java
@@ -0,0 +1,652 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalLockQueryResponseProto}
+ */
+public  final class GlobalLockQueryResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalLockQueryResponseProto)
+    GlobalLockQueryResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalLockQueryResponseProto.newBuilder() to construct.
+  private GlobalLockQueryResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalLockQueryResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalLockQueryResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder subBuilder = null;
+            if (abstractTransactionResponse_ != null) {
+              subBuilder = abstractTransactionResponse_.toBuilder();
+            }
+            abstractTransactionResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractTransactionResponse_);
+              abstractTransactionResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 16: {
+
+            lockable_ = input.readBool();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalLockQueryResponse.internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalLockQueryResponse.internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.class, io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public boolean hasAbstractTransactionResponse() {
+    return abstractTransactionResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+    return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+    return getAbstractTransactionResponse();
+  }
+
+  public static final int LOCKABLE_FIELD_NUMBER = 2;
+  private boolean lockable_;
+  /**
+   * <code>bool lockable = 2;</code>
+   */
+  public boolean getLockable() {
+    return lockable_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractTransactionResponse_ != null) {
+      output.writeMessage(1, getAbstractTransactionResponse());
+    }
+    if (lockable_ != false) {
+      output.writeBool(2, lockable_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractTransactionResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractTransactionResponse());
+    }
+    if (lockable_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(2, lockable_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto other = (io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto) obj;
+
+    if (hasAbstractTransactionResponse() != other.hasAbstractTransactionResponse()) return false;
+    if (hasAbstractTransactionResponse()) {
+      if (!getAbstractTransactionResponse()
+          .equals(other.getAbstractTransactionResponse())) return false;
+    }
+    if (getLockable()
+        != other.getLockable()) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractTransactionResponse()) {
+      hash = (37 * hash) + ABSTRACTTRANSACTIONRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractTransactionResponse().hashCode();
+    }
+    hash = (37 * hash) + LOCKABLE_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getLockable());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalLockQueryResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalLockQueryResponseProto)
+      io.seata.codec.protobuf.generated.GlobalLockQueryResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryResponse.internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryResponse.internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.class, io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+      lockable_ = false;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryResponse.internal_static_io_seata_protocol_protobuf_GlobalLockQueryResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto build() {
+      io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto result = new io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto(this);
+      if (abstractTransactionResponseBuilder_ == null) {
+        result.abstractTransactionResponse_ = abstractTransactionResponse_;
+      } else {
+        result.abstractTransactionResponse_ = abstractTransactionResponseBuilder_.build();
+      }
+      result.lockable_ = lockable_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractTransactionResponse()) {
+        mergeAbstractTransactionResponse(other.getAbstractTransactionResponse());
+      }
+      if (other.getLockable() != false) {
+        setLockable(other.getLockable());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractTransactionResponseProto abstractTransactionResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> abstractTransactionResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public boolean hasAbstractTransactionResponse() {
+      return abstractTransactionResponseBuilder_ != null || abstractTransactionResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        return abstractTransactionResponse_ == null ? io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      } else {
+        return abstractTransactionResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractTransactionResponse_ = value;
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder setAbstractTransactionResponse(
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder builderForValue) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder mergeAbstractTransactionResponse(io.seata.codec.protobuf.generated.AbstractTransactionResponseProto value) {
+      if (abstractTransactionResponseBuilder_ == null) {
+        if (abstractTransactionResponse_ != null) {
+          abstractTransactionResponse_ =
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.newBuilder(abstractTransactionResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractTransactionResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractTransactionResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public Builder clearAbstractTransactionResponse() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponse_ = null;
+        onChanged();
+      } else {
+        abstractTransactionResponse_ = null;
+        abstractTransactionResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder getAbstractTransactionResponseBuilder() {
+      
+      onChanged();
+      return getAbstractTransactionResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder() {
+      if (abstractTransactionResponseBuilder_ != null) {
+        return abstractTransactionResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractTransactionResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.getDefaultInstance() : abstractTransactionResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder> 
+        getAbstractTransactionResponseFieldBuilder() {
+      if (abstractTransactionResponseBuilder_ == null) {
+        abstractTransactionResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractTransactionResponseProto, io.seata.codec.protobuf.generated.AbstractTransactionResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder>(
+                getAbstractTransactionResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractTransactionResponse_ = null;
+      }
+      return abstractTransactionResponseBuilder_;
+    }
+
+    private boolean lockable_ ;
+    /**
+     * <code>bool lockable = 2;</code>
+     */
+    public boolean getLockable() {
+      return lockable_;
+    }
+    /**
+     * <code>bool lockable = 2;</code>
+     */
+    public Builder setLockable(boolean value) {
+      
+      lockable_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>bool lockable = 2;</code>
+     */
+    public Builder clearLockable() {
+      
+      lockable_ = false;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalLockQueryResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalLockQueryResponseProto)
+  private static final io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalLockQueryResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalLockQueryResponseProto>() {
+    @java.lang.Override
+    public GlobalLockQueryResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalLockQueryResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalLockQueryResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalLockQueryResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5b73eb9f8c3bdd68ec69d9eebae593c8f6321fb
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalLockQueryResponseProtoOrBuilder.java
@@ -0,0 +1,27 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalLockQueryResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalLockQueryResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalLockQueryResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  boolean hasAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProto getAbstractTransactionResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractTransactionResponseProto abstractTransactionResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractTransactionResponseProtoOrBuilder getAbstractTransactionResponseOrBuilder();
+
+  /**
+   * <code>bool lockable = 2;</code>
+   */
+  boolean getLockable();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8071ce5f933cc72072f9a37799d6e33032fa919d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequest.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalRollbackRequest {
+  private GlobalRollbackRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\033globalRollbackRequest.proto\022\032io.seata." +
+      "protocol.protobuf\032\036abstractGlobalEndRequ" +
+      "est.proto\"y\n\032GlobalRollbackRequestProto\022" +
+      "[\n\030abstractGlobalEndRequest\030\001 \001(\01329.io.s" +
+      "eata.protocol.protobuf.AbstractGlobalEnd" +
+      "RequestProtoB<\n!io.seata.codec.protobuf." +
+      "generatedB\025GlobalRollbackRequestP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndRequest", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcf1920ea98966f8dea207e41ec4c948268ccfc2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalRollbackRequestProto}
+ */
+public  final class GlobalRollbackRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalRollbackRequestProto)
+    GlobalRollbackRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalRollbackRequestProto.newBuilder() to construct.
+  private GlobalRollbackRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalRollbackRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalRollbackRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder subBuilder = null;
+            if (abstractGlobalEndRequest_ != null) {
+              subBuilder = abstractGlobalEndRequest_.toBuilder();
+            }
+            abstractGlobalEndRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndRequest_);
+              abstractGlobalEndRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalRollbackRequest.internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalRollbackRequest.internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.class, io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+    return getAbstractGlobalEndRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndRequest_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalRollbackRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalRollbackRequestProto other = (io.seata.codec.protobuf.generated.GlobalRollbackRequestProto) obj;
+
+    if (hasAbstractGlobalEndRequest() != other.hasAbstractGlobalEndRequest()) return false;
+    if (hasAbstractGlobalEndRequest()) {
+      if (!getAbstractGlobalEndRequest()
+          .equals(other.getAbstractGlobalEndRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndRequest()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalRollbackRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalRollbackRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalRollbackRequestProto)
+      io.seata.codec.protobuf.generated.GlobalRollbackRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackRequest.internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackRequest.internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.class, io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackRequest.internal_static_io_seata_protocol_protobuf_GlobalRollbackRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackRequestProto build() {
+      io.seata.codec.protobuf.generated.GlobalRollbackRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalRollbackRequestProto result = new io.seata.codec.protobuf.generated.GlobalRollbackRequestProto(this);
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequest_;
+      } else {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalRollbackRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalRollbackRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalRollbackRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalRollbackRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndRequest()) {
+        mergeAbstractGlobalEndRequest(other.getAbstractGlobalEndRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalRollbackRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalRollbackRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> abstractGlobalEndRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndRequest() {
+      return abstractGlobalEndRequestBuilder_ != null || abstractGlobalEndRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      } else {
+        return abstractGlobalEndRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndRequest_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder builderForValue) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (abstractGlobalEndRequest_ != null) {
+          abstractGlobalEndRequest_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.newBuilder(abstractGlobalEndRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder getAbstractGlobalEndRequestBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+      if (abstractGlobalEndRequestBuilder_ != null) {
+        return abstractGlobalEndRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> 
+        getAbstractGlobalEndRequestFieldBuilder() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder>(
+                getAbstractGlobalEndRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndRequest_ = null;
+      }
+      return abstractGlobalEndRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalRollbackRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalRollbackRequestProto)
+  private static final io.seata.codec.protobuf.generated.GlobalRollbackRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalRollbackRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalRollbackRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalRollbackRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalRollbackRequestProto>() {
+    @java.lang.Override
+    public GlobalRollbackRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalRollbackRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalRollbackRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalRollbackRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalRollbackRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd68a5ca6282202dba6bebf958472c7a272832a7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalRollbackRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalRollbackRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  boolean hasAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c2fa29b72be9805fa603215aa82150a730fe924
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalRollbackResponse {
+  private GlobalRollbackResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\034globalRollbackResponse.proto\022\032io.seata" +
+      ".protocol.protobuf\032\037abstractGlobalEndRes" +
+      "ponse.proto\"|\n\033GlobalRollbackResponsePro" +
+      "to\022]\n\031abstractGlobalEndResponse\030\001 \001(\0132:." +
+      "io.seata.protocol.protobuf.AbstractGloba" +
+      "lEndResponseProtoB=\n!io.seata.codec.prot" +
+      "obuf.generatedB\026GlobalRollbackResponseP\001" +
+      "b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndResponse", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..fe014a7cf3fd4851f8b4a25e5c1000a0841d7c9e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalRollbackResponseProto}
+ */
+public  final class GlobalRollbackResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalRollbackResponseProto)
+    GlobalRollbackResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalRollbackResponseProto.newBuilder() to construct.
+  private GlobalRollbackResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalRollbackResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalRollbackResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder subBuilder = null;
+            if (abstractGlobalEndResponse_ != null) {
+              subBuilder = abstractGlobalEndResponse_.toBuilder();
+            }
+            abstractGlobalEndResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndResponse_);
+              abstractGlobalEndResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalRollbackResponse.internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalRollbackResponse.internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.class, io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+    return getAbstractGlobalEndResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndResponse_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalRollbackResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalRollbackResponseProto other = (io.seata.codec.protobuf.generated.GlobalRollbackResponseProto) obj;
+
+    if (hasAbstractGlobalEndResponse() != other.hasAbstractGlobalEndResponse()) return false;
+    if (hasAbstractGlobalEndResponse()) {
+      if (!getAbstractGlobalEndResponse()
+          .equals(other.getAbstractGlobalEndResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndResponse()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalRollbackResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalRollbackResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalRollbackResponseProto)
+      io.seata.codec.protobuf.generated.GlobalRollbackResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackResponse.internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackResponse.internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.class, io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackResponse.internal_static_io_seata_protocol_protobuf_GlobalRollbackResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackResponseProto build() {
+      io.seata.codec.protobuf.generated.GlobalRollbackResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalRollbackResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalRollbackResponseProto result = new io.seata.codec.protobuf.generated.GlobalRollbackResponseProto(this);
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponse_;
+      } else {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalRollbackResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalRollbackResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalRollbackResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalRollbackResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndResponse()) {
+        mergeAbstractGlobalEndResponse(other.getAbstractGlobalEndResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalRollbackResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalRollbackResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> abstractGlobalEndResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndResponse() {
+      return abstractGlobalEndResponseBuilder_ != null || abstractGlobalEndResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      } else {
+        return abstractGlobalEndResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndResponse_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder builderForValue) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (abstractGlobalEndResponse_ != null) {
+          abstractGlobalEndResponse_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.newBuilder(abstractGlobalEndResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder getAbstractGlobalEndResponseBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+      if (abstractGlobalEndResponseBuilder_ != null) {
+        return abstractGlobalEndResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> 
+        getAbstractGlobalEndResponseFieldBuilder() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder>(
+                getAbstractGlobalEndResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndResponse_ = null;
+      }
+      return abstractGlobalEndResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalRollbackResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalRollbackResponseProto)
+  private static final io.seata.codec.protobuf.generated.GlobalRollbackResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalRollbackResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalRollbackResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalRollbackResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalRollbackResponseProto>() {
+    @java.lang.Override
+    public GlobalRollbackResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalRollbackResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalRollbackResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalRollbackResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalRollbackResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..326e86ad65c2e41c66e1c17ae2c196dae829da78
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalRollbackResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalRollbackResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalRollbackResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalRollbackResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  boolean hasAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatus.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..6b97208ee0a1c046227c442a76fd7c9116fa4098
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatus.java
@@ -0,0 +1,53 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatus.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalStatus {
+  private GlobalStatus() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\022globalStatus.proto\022\032io.seata.protocol." +
+      "protobuf*\305\002\n\021GlobalStatusProto\022\013\n\007UnKnow" +
+      "n\020\000\022\t\n\005Begin\020\001\022\016\n\nCommitting\020\002\022\022\n\016Commit" +
+      "Retrying\020\003\022\017\n\013Rollbacking\020\004\022\024\n\020RollbackR" +
+      "etrying\020\005\022\026\n\022TimeoutRollbacking\020\006\022\033\n\027Tim" +
+      "eoutRollbackRetrying\020\007\022\023\n\017AsyncCommittin" +
+      "g\020\010\022\r\n\tCommitted\020\t\022\020\n\014CommitFailed\020\n\022\016\n\n" +
+      "Rollbacked\020\013\022\022\n\016RollbackFailed\020\014\022\025\n\021Time" +
+      "outRollbacked\020\r\022\031\n\025TimeoutRollbackFailed" +
+      "\020\016\022\014\n\010Finished\020\017B3\n!io.seata.codec.proto" +
+      "buf.generatedB\014GlobalStatusP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..48eda72ada032117c62fcf68c6d1aacc9c5de457
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusProto.java
@@ -0,0 +1,365 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatus.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.GlobalStatusProto}
+ */
+public enum GlobalStatusProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <pre>
+   * Unknown
+   * </pre>
+   *
+   * <code>UnKnown = 0;</code>
+   */
+  UnKnown(0),
+  /**
+   * <pre>
+   * PHASE 1: can accept new branch registering.
+   * </pre>
+   *
+   * <code>Begin = 1;</code>
+   */
+  Begin(1),
+  /**
+   * <pre>
+   * Committing.
+   * </pre>
+   *
+   * <code>Committing = 2;</code>
+   */
+  Committing(2),
+  /**
+   * <pre>
+   * Retrying commit after a recoverable failure.
+   * </pre>
+   *
+   * <code>CommitRetrying = 3;</code>
+   */
+  CommitRetrying(3),
+  /**
+   * <pre>
+   * Rollbacking
+   * </pre>
+   *
+   * <code>Rollbacking = 4;</code>
+   */
+  Rollbacking(4),
+  /**
+   * <pre>
+   * Retrying rollback after a recoverable failure.
+   * </pre>
+   *
+   * <code>RollbackRetrying = 5;</code>
+   */
+  RollbackRetrying(5),
+  /**
+   * <pre>
+   * Rollbacking since timeout
+   * </pre>
+   *
+   * <code>TimeoutRollbacking = 6;</code>
+   */
+  TimeoutRollbacking(6),
+  /**
+   * <pre>
+   * Retrying rollback (since timeout) after a recoverable failure.
+   * </pre>
+   *
+   * <code>TimeoutRollbackRetrying = 7;</code>
+   */
+  TimeoutRollbackRetrying(7),
+  /**
+   * <pre>
+   **
+   * All branches can be async committed. The committing is NOT done yet, but it can be seen as committed for TM/RM
+   * client.
+   * </pre>
+   *
+   * <code>AsyncCommitting = 8;</code>
+   */
+  AsyncCommitting(8),
+  /**
+   * <pre>
+   * Finally: global transaction is successfully committed.
+   * </pre>
+   *
+   * <code>Committed = 9;</code>
+   */
+  Committed(9),
+  /**
+   * <pre>
+   * Finally: failed to commit
+   * </pre>
+   *
+   * <code>CommitFailed = 10;</code>
+   */
+  CommitFailed(10),
+  /**
+   * <pre>
+   * Finally: global transaction is successfully rollbacked.
+   * </pre>
+   *
+   * <code>Rollbacked = 11;</code>
+   */
+  Rollbacked(11),
+  /**
+   * <pre>
+   * Finally: failed to rollback
+   * </pre>
+   *
+   * <code>RollbackFailed = 12;</code>
+   */
+  RollbackFailed(12),
+  /**
+   * <pre>
+   * Finally: global transaction is successfully rollbacked since timeout.
+   * </pre>
+   *
+   * <code>TimeoutRollbacked = 13;</code>
+   */
+  TimeoutRollbacked(13),
+  /**
+   * <pre>
+   * Finally: failed to rollback since timeout
+   * </pre>
+   *
+   * <code>TimeoutRollbackFailed = 14;</code>
+   */
+  TimeoutRollbackFailed(14),
+  /**
+   * <pre>
+   * Not managed in session MAP any more
+   * </pre>
+   *
+   * <code>Finished = 15;</code>
+   */
+  Finished(15),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <pre>
+   * Unknown
+   * </pre>
+   *
+   * <code>UnKnown = 0;</code>
+   */
+  public static final int UnKnown_VALUE = 0;
+  /**
+   * <pre>
+   * PHASE 1: can accept new branch registering.
+   * </pre>
+   *
+   * <code>Begin = 1;</code>
+   */
+  public static final int Begin_VALUE = 1;
+  /**
+   * <pre>
+   * Committing.
+   * </pre>
+   *
+   * <code>Committing = 2;</code>
+   */
+  public static final int Committing_VALUE = 2;
+  /**
+   * <pre>
+   * Retrying commit after a recoverable failure.
+   * </pre>
+   *
+   * <code>CommitRetrying = 3;</code>
+   */
+  public static final int CommitRetrying_VALUE = 3;
+  /**
+   * <pre>
+   * Rollbacking
+   * </pre>
+   *
+   * <code>Rollbacking = 4;</code>
+   */
+  public static final int Rollbacking_VALUE = 4;
+  /**
+   * <pre>
+   * Retrying rollback after a recoverable failure.
+   * </pre>
+   *
+   * <code>RollbackRetrying = 5;</code>
+   */
+  public static final int RollbackRetrying_VALUE = 5;
+  /**
+   * <pre>
+   * Rollbacking since timeout
+   * </pre>
+   *
+   * <code>TimeoutRollbacking = 6;</code>
+   */
+  public static final int TimeoutRollbacking_VALUE = 6;
+  /**
+   * <pre>
+   * Retrying rollback (since timeout) after a recoverable failure.
+   * </pre>
+   *
+   * <code>TimeoutRollbackRetrying = 7;</code>
+   */
+  public static final int TimeoutRollbackRetrying_VALUE = 7;
+  /**
+   * <pre>
+   **
+   * All branches can be async committed. The committing is NOT done yet, but it can be seen as committed for TM/RM
+   * client.
+   * </pre>
+   *
+   * <code>AsyncCommitting = 8;</code>
+   */
+  public static final int AsyncCommitting_VALUE = 8;
+  /**
+   * <pre>
+   * Finally: global transaction is successfully committed.
+   * </pre>
+   *
+   * <code>Committed = 9;</code>
+   */
+  public static final int Committed_VALUE = 9;
+  /**
+   * <pre>
+   * Finally: failed to commit
+   * </pre>
+   *
+   * <code>CommitFailed = 10;</code>
+   */
+  public static final int CommitFailed_VALUE = 10;
+  /**
+   * <pre>
+   * Finally: global transaction is successfully rollbacked.
+   * </pre>
+   *
+   * <code>Rollbacked = 11;</code>
+   */
+  public static final int Rollbacked_VALUE = 11;
+  /**
+   * <pre>
+   * Finally: failed to rollback
+   * </pre>
+   *
+   * <code>RollbackFailed = 12;</code>
+   */
+  public static final int RollbackFailed_VALUE = 12;
+  /**
+   * <pre>
+   * Finally: global transaction is successfully rollbacked since timeout.
+   * </pre>
+   *
+   * <code>TimeoutRollbacked = 13;</code>
+   */
+  public static final int TimeoutRollbacked_VALUE = 13;
+  /**
+   * <pre>
+   * Finally: failed to rollback since timeout
+   * </pre>
+   *
+   * <code>TimeoutRollbackFailed = 14;</code>
+   */
+  public static final int TimeoutRollbackFailed_VALUE = 14;
+  /**
+   * <pre>
+   * Not managed in session MAP any more
+   * </pre>
+   *
+   * <code>Finished = 15;</code>
+   */
+  public static final int Finished_VALUE = 15;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static GlobalStatusProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static GlobalStatusProto forNumber(int value) {
+    switch (value) {
+      case 0: return UnKnown;
+      case 1: return Begin;
+      case 2: return Committing;
+      case 3: return CommitRetrying;
+      case 4: return Rollbacking;
+      case 5: return RollbackRetrying;
+      case 6: return TimeoutRollbacking;
+      case 7: return TimeoutRollbackRetrying;
+      case 8: return AsyncCommitting;
+      case 9: return Committed;
+      case 10: return CommitFailed;
+      case 11: return Rollbacked;
+      case 12: return RollbackFailed;
+      case 13: return TimeoutRollbacked;
+      case 14: return TimeoutRollbackFailed;
+      case 15: return Finished;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<GlobalStatusProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      GlobalStatusProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<GlobalStatusProto>() {
+          public GlobalStatusProto findValueByNumber(int number) {
+            return GlobalStatusProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalStatus.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final GlobalStatusProto[] VALUES = values();
+
+  public static GlobalStatusProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private GlobalStatusProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.GlobalStatusProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddd8b7151b8c9319460953861326620bcc0b3659
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalStatusRequest {
+  private GlobalStatusRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031globalStatusRequest.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032\036abstractGlobalEndReques" +
+      "t.proto\"w\n\030GlobalStatusRequestProto\022[\n\030a" +
+      "bstractGlobalEndRequest\030\001 \001(\01329.io.seata" +
+      ".protocol.protobuf.AbstractGlobalEndRequ" +
+      "estProtoB:\n!io.seata.codec.protobuf.gene" +
+      "ratedB\023GlobalStatusRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndRequest", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..980381370591305f0eff1958a33926d603e7ef13
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalStatusRequestProto}
+ */
+public  final class GlobalStatusRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalStatusRequestProto)
+    GlobalStatusRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalStatusRequestProto.newBuilder() to construct.
+  private GlobalStatusRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalStatusRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalStatusRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder subBuilder = null;
+            if (abstractGlobalEndRequest_ != null) {
+              subBuilder = abstractGlobalEndRequest_.toBuilder();
+            }
+            abstractGlobalEndRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndRequest_);
+              abstractGlobalEndRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalStatusRequest.internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalStatusRequest.internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalStatusRequestProto.class, io.seata.codec.protobuf.generated.GlobalStatusRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+    return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+    return getAbstractGlobalEndRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndRequest_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalStatusRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalStatusRequestProto other = (io.seata.codec.protobuf.generated.GlobalStatusRequestProto) obj;
+
+    if (hasAbstractGlobalEndRequest() != other.hasAbstractGlobalEndRequest()) return false;
+    if (hasAbstractGlobalEndRequest()) {
+      if (!getAbstractGlobalEndRequest()
+          .equals(other.getAbstractGlobalEndRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndRequest()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalStatusRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalStatusRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalStatusRequestProto)
+      io.seata.codec.protobuf.generated.GlobalStatusRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalStatusRequest.internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalStatusRequest.internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalStatusRequestProto.class, io.seata.codec.protobuf.generated.GlobalStatusRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalStatusRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalStatusRequest.internal_static_io_seata_protocol_protobuf_GlobalStatusRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalStatusRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusRequestProto build() {
+      io.seata.codec.protobuf.generated.GlobalStatusRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalStatusRequestProto result = new io.seata.codec.protobuf.generated.GlobalStatusRequestProto(this);
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequest_;
+      } else {
+        result.abstractGlobalEndRequest_ = abstractGlobalEndRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalStatusRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalStatusRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalStatusRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalStatusRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndRequest()) {
+        mergeAbstractGlobalEndRequest(other.getAbstractGlobalEndRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalStatusRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalStatusRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto abstractGlobalEndRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> abstractGlobalEndRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndRequest() {
+      return abstractGlobalEndRequestBuilder_ != null || abstractGlobalEndRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        return abstractGlobalEndRequest_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      } else {
+        return abstractGlobalEndRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndRequest_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder setAbstractGlobalEndRequest(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder builderForValue) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndRequest(io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto value) {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        if (abstractGlobalEndRequest_ != null) {
+          abstractGlobalEndRequest_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.newBuilder(abstractGlobalEndRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndRequest() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequest_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndRequest_ = null;
+        abstractGlobalEndRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder getAbstractGlobalEndRequestBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder() {
+      if (abstractGlobalEndRequestBuilder_ != null) {
+        return abstractGlobalEndRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.getDefaultInstance() : abstractGlobalEndRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder> 
+        getAbstractGlobalEndRequestFieldBuilder() {
+      if (abstractGlobalEndRequestBuilder_ == null) {
+        abstractGlobalEndRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder>(
+                getAbstractGlobalEndRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndRequest_ = null;
+      }
+      return abstractGlobalEndRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalStatusRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalStatusRequestProto)
+  private static final io.seata.codec.protobuf.generated.GlobalStatusRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalStatusRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalStatusRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalStatusRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalStatusRequestProto>() {
+    @java.lang.Override
+    public GlobalStatusRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalStatusRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalStatusRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalStatusRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalStatusRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..08a51add4535cf92a6ae1951a31f3fe771b35df7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalStatusRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalStatusRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  boolean hasAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProto getAbstractGlobalEndRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndRequestProtoOrBuilder getAbstractGlobalEndRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..39c96f703595f58729d18ade3f30cc563c2c4f22
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponse.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class GlobalStatusResponse {
+  private GlobalStatusResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\032globalStatusResponse.proto\022\032io.seata.p" +
+      "rotocol.protobuf\032\037abstractGlobalEndRespo" +
+      "nse.proto\"z\n\031GlobalStatusResponseProto\022]" +
+      "\n\031abstractGlobalEndResponse\030\001 \001(\0132:.io.s" +
+      "eata.protocol.protobuf.AbstractGlobalEnd" +
+      "ResponseProtoB;\n!io.seata.codec.protobuf" +
+      ".generatedB\024GlobalStatusResponseP\001b\006prot" +
+      "o3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor,
+        new java.lang.String[] { "AbstractGlobalEndResponse", });
+    io.seata.codec.protobuf.generated.AbstractGlobalEndResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2023faa6a01645e2d0284e93b4fc9681d12c58c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProto.java
@@ -0,0 +1,594 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * Protobuf type {@code io.seata.protocol.protobuf.GlobalStatusResponseProto}
+ */
+public  final class GlobalStatusResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.GlobalStatusResponseProto)
+    GlobalStatusResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use GlobalStatusResponseProto.newBuilder() to construct.
+  private GlobalStatusResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private GlobalStatusResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private GlobalStatusResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder subBuilder = null;
+            if (abstractGlobalEndResponse_ != null) {
+              subBuilder = abstractGlobalEndResponse_.toBuilder();
+            }
+            abstractGlobalEndResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractGlobalEndResponse_);
+              abstractGlobalEndResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.GlobalStatusResponse.internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.GlobalStatusResponse.internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.GlobalStatusResponseProto.class, io.seata.codec.protobuf.generated.GlobalStatusResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public boolean hasAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+    return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+    return getAbstractGlobalEndResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractGlobalEndResponse_ != null) {
+      output.writeMessage(1, getAbstractGlobalEndResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractGlobalEndResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractGlobalEndResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.GlobalStatusResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.GlobalStatusResponseProto other = (io.seata.codec.protobuf.generated.GlobalStatusResponseProto) obj;
+
+    if (hasAbstractGlobalEndResponse() != other.hasAbstractGlobalEndResponse()) return false;
+    if (hasAbstractGlobalEndResponse()) {
+      if (!getAbstractGlobalEndResponse()
+          .equals(other.getAbstractGlobalEndResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractGlobalEndResponse()) {
+      hash = (37 * hash) + ABSTRACTGLOBALENDRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractGlobalEndResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.GlobalStatusResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code io.seata.protocol.protobuf.GlobalStatusResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.GlobalStatusResponseProto)
+      io.seata.codec.protobuf.generated.GlobalStatusResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.GlobalStatusResponse.internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.GlobalStatusResponse.internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.GlobalStatusResponseProto.class, io.seata.codec.protobuf.generated.GlobalStatusResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.GlobalStatusResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.GlobalStatusResponse.internal_static_io_seata_protocol_protobuf_GlobalStatusResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.GlobalStatusResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusResponseProto build() {
+      io.seata.codec.protobuf.generated.GlobalStatusResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.GlobalStatusResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.GlobalStatusResponseProto result = new io.seata.codec.protobuf.generated.GlobalStatusResponseProto(this);
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponse_;
+      } else {
+        result.abstractGlobalEndResponse_ = abstractGlobalEndResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.GlobalStatusResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.GlobalStatusResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.GlobalStatusResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.GlobalStatusResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractGlobalEndResponse()) {
+        mergeAbstractGlobalEndResponse(other.getAbstractGlobalEndResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.GlobalStatusResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.GlobalStatusResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto abstractGlobalEndResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> abstractGlobalEndResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public boolean hasAbstractGlobalEndResponse() {
+      return abstractGlobalEndResponseBuilder_ != null || abstractGlobalEndResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        return abstractGlobalEndResponse_ == null ? io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      } else {
+        return abstractGlobalEndResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractGlobalEndResponse_ = value;
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder setAbstractGlobalEndResponse(
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder builderForValue) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder mergeAbstractGlobalEndResponse(io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto value) {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        if (abstractGlobalEndResponse_ != null) {
+          abstractGlobalEndResponse_ =
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.newBuilder(abstractGlobalEndResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractGlobalEndResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractGlobalEndResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public Builder clearAbstractGlobalEndResponse() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponse_ = null;
+        onChanged();
+      } else {
+        abstractGlobalEndResponse_ = null;
+        abstractGlobalEndResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder getAbstractGlobalEndResponseBuilder() {
+      
+      onChanged();
+      return getAbstractGlobalEndResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder() {
+      if (abstractGlobalEndResponseBuilder_ != null) {
+        return abstractGlobalEndResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractGlobalEndResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.getDefaultInstance() : abstractGlobalEndResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder> 
+        getAbstractGlobalEndResponseFieldBuilder() {
+      if (abstractGlobalEndResponseBuilder_ == null) {
+        abstractGlobalEndResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder>(
+                getAbstractGlobalEndResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractGlobalEndResponse_ = null;
+      }
+      return abstractGlobalEndResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.GlobalStatusResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.GlobalStatusResponseProto)
+  private static final io.seata.codec.protobuf.generated.GlobalStatusResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.GlobalStatusResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.GlobalStatusResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<GlobalStatusResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<GlobalStatusResponseProto>() {
+    @java.lang.Override
+    public GlobalStatusResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new GlobalStatusResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<GlobalStatusResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<GlobalStatusResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.GlobalStatusResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..345bb4d693f51b868a04f22358e09334c828d3a2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/GlobalStatusResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: globalStatusResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface GlobalStatusResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.GlobalStatusResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  boolean hasAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProto getAbstractGlobalEndResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractGlobalEndResponseProtoOrBuilder getAbstractGlobalEndResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessage.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..d06ad556c749c35f4779305db3faed7959a638a4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessage.java
@@ -0,0 +1,57 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: heartbeatMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class HeartbeatMessage {
+  private HeartbeatMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026heartbeatMessage.proto\022\032io.seata.proto" +
+      "col.protobuf\"%\n\025HeartbeatMessageProto\022\014\n" +
+      "\004ping\030\001 \001(\010B7\n!io.seata.codec.protobuf.g" +
+      "eneratedB\020HeartbeatMessageP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor,
+        new java.lang.String[] { "Ping", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..023240931997353ec17153e17f909a52e5d1b8ab
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProto.java
@@ -0,0 +1,479 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: heartbeatMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.HeartbeatMessageProto}
+ */
+public  final class HeartbeatMessageProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.HeartbeatMessageProto)
+    HeartbeatMessageProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use HeartbeatMessageProto.newBuilder() to construct.
+  private HeartbeatMessageProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private HeartbeatMessageProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private HeartbeatMessageProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 8: {
+
+            ping_ = input.readBool();
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.HeartbeatMessage.internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.HeartbeatMessage.internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.HeartbeatMessageProto.class, io.seata.codec.protobuf.generated.HeartbeatMessageProto.Builder.class);
+  }
+
+  public static final int PING_FIELD_NUMBER = 1;
+  private boolean ping_;
+  /**
+   * <code>bool ping = 1;</code>
+   */
+  public boolean getPing() {
+    return ping_;
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (ping_ != false) {
+      output.writeBool(1, ping_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (ping_ != false) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeBoolSize(1, ping_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.HeartbeatMessageProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.HeartbeatMessageProto other = (io.seata.codec.protobuf.generated.HeartbeatMessageProto) obj;
+
+    if (getPing()
+        != other.getPing()) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + PING_FIELD_NUMBER;
+    hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+        getPing());
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.HeartbeatMessageProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.HeartbeatMessageProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.HeartbeatMessageProto)
+      io.seata.codec.protobuf.generated.HeartbeatMessageProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.HeartbeatMessage.internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.HeartbeatMessage.internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.HeartbeatMessageProto.class, io.seata.codec.protobuf.generated.HeartbeatMessageProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.HeartbeatMessageProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      ping_ = false;
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.HeartbeatMessage.internal_static_io_seata_protocol_protobuf_HeartbeatMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.HeartbeatMessageProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.HeartbeatMessageProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.HeartbeatMessageProto build() {
+      io.seata.codec.protobuf.generated.HeartbeatMessageProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.HeartbeatMessageProto buildPartial() {
+      io.seata.codec.protobuf.generated.HeartbeatMessageProto result = new io.seata.codec.protobuf.generated.HeartbeatMessageProto(this);
+      result.ping_ = ping_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.HeartbeatMessageProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.HeartbeatMessageProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.HeartbeatMessageProto other) {
+      if (other == io.seata.codec.protobuf.generated.HeartbeatMessageProto.getDefaultInstance()) return this;
+      if (other.getPing() != false) {
+        setPing(other.getPing());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.HeartbeatMessageProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.HeartbeatMessageProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private boolean ping_ ;
+    /**
+     * <code>bool ping = 1;</code>
+     */
+    public boolean getPing() {
+      return ping_;
+    }
+    /**
+     * <code>bool ping = 1;</code>
+     */
+    public Builder setPing(boolean value) {
+      
+      ping_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>bool ping = 1;</code>
+     */
+    public Builder clearPing() {
+      
+      ping_ = false;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.HeartbeatMessageProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.HeartbeatMessageProto)
+  private static final io.seata.codec.protobuf.generated.HeartbeatMessageProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.HeartbeatMessageProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.HeartbeatMessageProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<HeartbeatMessageProto>
+      PARSER = new com.google.protobuf.AbstractParser<HeartbeatMessageProto>() {
+    @java.lang.Override
+    public HeartbeatMessageProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new HeartbeatMessageProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<HeartbeatMessageProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<HeartbeatMessageProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.HeartbeatMessageProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd70ed05686f3d6665a80e9a2ed2e31ba8ab7761
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/HeartbeatMessageProtoOrBuilder.java
@@ -0,0 +1,14 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: heartbeatMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface HeartbeatMessageProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.HeartbeatMessageProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>bool ping = 1;</code>
+   */
+  boolean getPing();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessage.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..87e601f1991dcfad850b9878f469f7eddd30ba08
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessage.java
@@ -0,0 +1,65 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class MergedResultMessage {
+  private MergedResultMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\031mergedResultMessage.proto\022\032io.seata.pr" +
+      "otocol.protobuf\032\025abstractMessage.proto\032\031" +
+      "google/protobuf/any.proto\"\211\001\n\030MergedResu" +
+      "ltMessageProto\022I\n\017abstractMessage\030\001 \001(\0132" +
+      "0.io.seata.protocol.protobuf.AbstractMes" +
+      "sageProto\022\"\n\004msgs\030\002 \003(\0132\024.google.protobu" +
+      "f.AnyB:\n!io.seata.codec.protobuf.generat" +
+      "edB\023MergedResultMessageP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor(),
+          com.google.protobuf.AnyProto.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor,
+        new java.lang.String[] { "AbstractMessage", "Msgs", });
+    io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor();
+    com.google.protobuf.AnyProto.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..f934a50e428274f275bf34e9d4fdd37dec1f4ad9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProto.java
@@ -0,0 +1,950 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.MergedResultMessageProto}
+ */
+public  final class MergedResultMessageProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.MergedResultMessageProto)
+    MergedResultMessageProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use MergedResultMessageProto.newBuilder() to construct.
+  private MergedResultMessageProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private MergedResultMessageProto() {
+    msgs_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private MergedResultMessageProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractMessageProto.Builder subBuilder = null;
+            if (abstractMessage_ != null) {
+              subBuilder = abstractMessage_.toBuilder();
+            }
+            abstractMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractMessage_);
+              abstractMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+              msgs_ = new java.util.ArrayList<com.google.protobuf.Any>();
+              mutable_bitField0_ |= 0x00000002;
+            }
+            msgs_.add(
+                input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry));
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000002) != 0)) {
+        msgs_ = java.util.Collections.unmodifiableList(msgs_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.MergedResultMessage.internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.MergedResultMessage.internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.MergedResultMessageProto.class, io.seata.codec.protobuf.generated.MergedResultMessageProto.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int ABSTRACTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public boolean hasAbstractMessage() {
+    return abstractMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+    return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+    return getAbstractMessage();
+  }
+
+  public static final int MSGS_FIELD_NUMBER = 2;
+  private java.util.List<com.google.protobuf.Any> msgs_;
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public java.util.List<com.google.protobuf.Any> getMsgsList() {
+    return msgs_;
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+      getMsgsOrBuilderList() {
+    return msgs_;
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public int getMsgsCount() {
+    return msgs_.size();
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public com.google.protobuf.Any getMsgs(int index) {
+    return msgs_.get(index);
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+      int index) {
+    return msgs_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractMessage_ != null) {
+      output.writeMessage(1, getAbstractMessage());
+    }
+    for (int i = 0; i < msgs_.size(); i++) {
+      output.writeMessage(2, msgs_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractMessage());
+    }
+    for (int i = 0; i < msgs_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, msgs_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.MergedResultMessageProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.MergedResultMessageProto other = (io.seata.codec.protobuf.generated.MergedResultMessageProto) obj;
+
+    if (hasAbstractMessage() != other.hasAbstractMessage()) return false;
+    if (hasAbstractMessage()) {
+      if (!getAbstractMessage()
+          .equals(other.getAbstractMessage())) return false;
+    }
+    if (!getMsgsList()
+        .equals(other.getMsgsList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractMessage()) {
+      hash = (37 * hash) + ABSTRACTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractMessage().hashCode();
+    }
+    if (getMsgsCount() > 0) {
+      hash = (37 * hash) + MSGS_FIELD_NUMBER;
+      hash = (53 * hash) + getMsgsList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.MergedResultMessageProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.MergedResultMessageProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.MergedResultMessageProto)
+      io.seata.codec.protobuf.generated.MergedResultMessageProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.MergedResultMessage.internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.MergedResultMessage.internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.MergedResultMessageProto.class, io.seata.codec.protobuf.generated.MergedResultMessageProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.MergedResultMessageProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getMsgsFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+      if (msgsBuilder_ == null) {
+        msgs_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+      } else {
+        msgsBuilder_.clear();
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.MergedResultMessage.internal_static_io_seata_protocol_protobuf_MergedResultMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedResultMessageProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.MergedResultMessageProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedResultMessageProto build() {
+      io.seata.codec.protobuf.generated.MergedResultMessageProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedResultMessageProto buildPartial() {
+      io.seata.codec.protobuf.generated.MergedResultMessageProto result = new io.seata.codec.protobuf.generated.MergedResultMessageProto(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (abstractMessageBuilder_ == null) {
+        result.abstractMessage_ = abstractMessage_;
+      } else {
+        result.abstractMessage_ = abstractMessageBuilder_.build();
+      }
+      if (msgsBuilder_ == null) {
+        if (((bitField0_ & 0x00000002) != 0)) {
+          msgs_ = java.util.Collections.unmodifiableList(msgs_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.msgs_ = msgs_;
+      } else {
+        result.msgs_ = msgsBuilder_.build();
+      }
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.MergedResultMessageProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.MergedResultMessageProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.MergedResultMessageProto other) {
+      if (other == io.seata.codec.protobuf.generated.MergedResultMessageProto.getDefaultInstance()) return this;
+      if (other.hasAbstractMessage()) {
+        mergeAbstractMessage(other.getAbstractMessage());
+      }
+      if (msgsBuilder_ == null) {
+        if (!other.msgs_.isEmpty()) {
+          if (msgs_.isEmpty()) {
+            msgs_ = other.msgs_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureMsgsIsMutable();
+            msgs_.addAll(other.msgs_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.msgs_.isEmpty()) {
+          if (msgsBuilder_.isEmpty()) {
+            msgsBuilder_.dispose();
+            msgsBuilder_ = null;
+            msgs_ = other.msgs_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+            msgsBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getMsgsFieldBuilder() : null;
+          } else {
+            msgsBuilder_.addAllMessages(other.msgs_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.MergedResultMessageProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.MergedResultMessageProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> abstractMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public boolean hasAbstractMessage() {
+      return abstractMessageBuilder_ != null || abstractMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      } else {
+        return abstractMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractMessage_ = value;
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(
+        io.seata.codec.protobuf.generated.AbstractMessageProto.Builder builderForValue) {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder mergeAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (abstractMessage_ != null) {
+          abstractMessage_ =
+            io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder(abstractMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder clearAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+        onChanged();
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto.Builder getAbstractMessageBuilder() {
+      
+      onChanged();
+      return getAbstractMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+      if (abstractMessageBuilder_ != null) {
+        return abstractMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> 
+        getAbstractMessageFieldBuilder() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder>(
+                getAbstractMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractMessage_ = null;
+      }
+      return abstractMessageBuilder_;
+    }
+
+    private java.util.List<com.google.protobuf.Any> msgs_ =
+      java.util.Collections.emptyList();
+    private void ensureMsgsIsMutable() {
+      if (!((bitField0_ & 0x00000002) != 0)) {
+        msgs_ = new java.util.ArrayList<com.google.protobuf.Any>(msgs_);
+        bitField0_ |= 0x00000002;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> msgsBuilder_;
+
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<com.google.protobuf.Any> getMsgsList() {
+      if (msgsBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(msgs_);
+      } else {
+        return msgsBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public int getMsgsCount() {
+      if (msgsBuilder_ == null) {
+        return msgs_.size();
+      } else {
+        return msgsBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any getMsgs(int index) {
+      if (msgsBuilder_ == null) {
+        return msgs_.get(index);
+      } else {
+        return msgsBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder setMsgs(
+        int index, com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.set(index, value);
+        onChanged();
+      } else {
+        msgsBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder setMsgs(
+        int index, com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.add(value);
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        int index, com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.add(index, value);
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.add(builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        int index, com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addAllMsgs(
+        java.lang.Iterable<? extends com.google.protobuf.Any> values) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, msgs_);
+        onChanged();
+      } else {
+        msgsBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder clearMsgs() {
+      if (msgsBuilder_ == null) {
+        msgs_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        onChanged();
+      } else {
+        msgsBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder removeMsgs(int index) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.remove(index);
+        onChanged();
+      } else {
+        msgsBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder getMsgsBuilder(
+        int index) {
+      return getMsgsFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+        int index) {
+      if (msgsBuilder_ == null) {
+        return msgs_.get(index);  } else {
+        return msgsBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+         getMsgsOrBuilderList() {
+      if (msgsBuilder_ != null) {
+        return msgsBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(msgs_);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder addMsgsBuilder() {
+      return getMsgsFieldBuilder().addBuilder(
+          com.google.protobuf.Any.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder addMsgsBuilder(
+        int index) {
+      return getMsgsFieldBuilder().addBuilder(
+          index, com.google.protobuf.Any.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<com.google.protobuf.Any.Builder> 
+         getMsgsBuilderList() {
+      return getMsgsFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> 
+        getMsgsFieldBuilder() {
+      if (msgsBuilder_ == null) {
+        msgsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>(
+                msgs_,
+                ((bitField0_ & 0x00000002) != 0),
+                getParentForChildren(),
+                isClean());
+        msgs_ = null;
+      }
+      return msgsBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.MergedResultMessageProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.MergedResultMessageProto)
+  private static final io.seata.codec.protobuf.generated.MergedResultMessageProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.MergedResultMessageProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.MergedResultMessageProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<MergedResultMessageProto>
+      PARSER = new com.google.protobuf.AbstractParser<MergedResultMessageProto>() {
+    @java.lang.Override
+    public MergedResultMessageProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new MergedResultMessageProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<MergedResultMessageProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<MergedResultMessageProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.MergedResultMessageProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5242faec2b0e87f6957a815bc41e26adbbd03f8
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedResultMessageProtoOrBuilder.java
@@ -0,0 +1,46 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedResultMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface MergedResultMessageProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.MergedResultMessageProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  boolean hasAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder();
+
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  java.util.List<com.google.protobuf.Any> 
+      getMsgsList();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  com.google.protobuf.Any getMsgs(int index);
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  int getMsgsCount();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+      getMsgsOrBuilderList();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+      int index);
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessage.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..01921fb18b2552616c3a907feff29795f7321645
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessage.java
@@ -0,0 +1,66 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedWarpMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class MergedWarpMessage {
+  private MergedWarpMessage() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\027mergedWarpMessage.proto\022\032io.seata.prot" +
+      "ocol.protobuf\032\025abstractMessage.proto\032\031go" +
+      "ogle/protobuf/any.proto\"\227\001\n\026MergedWarpMe" +
+      "ssageProto\022I\n\017abstractMessage\030\001 \001(\01320.io" +
+      ".seata.protocol.protobuf.AbstractMessage" +
+      "Proto\022\"\n\004msgs\030\002 \003(\0132\024.google.protobuf.An" +
+      "y\022\016\n\006msgIds\030\003 \003(\005B8\n!io.seata.codec.prot" +
+      "obuf.generatedB\021MergedWarpMessageP\001b\006pro" +
+      "to3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor(),
+          com.google.protobuf.AnyProto.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor,
+        new java.lang.String[] { "AbstractMessage", "Msgs", "MsgIds", });
+    io.seata.codec.protobuf.generated.AbstractMessage.getDescriptor();
+    com.google.protobuf.AnyProto.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c74e4d72b74b61de78b432fd440bd54384c3143
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProto.java
@@ -0,0 +1,1110 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedWarpMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.MergedWarpMessageProto}
+ */
+public  final class MergedWarpMessageProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.MergedWarpMessageProto)
+    MergedWarpMessageProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use MergedWarpMessageProto.newBuilder() to construct.
+  private MergedWarpMessageProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private MergedWarpMessageProto() {
+    msgs_ = java.util.Collections.emptyList();
+    msgIds_ = emptyIntList();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private MergedWarpMessageProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractMessageProto.Builder subBuilder = null;
+            if (abstractMessage_ != null) {
+              subBuilder = abstractMessage_.toBuilder();
+            }
+            abstractMessage_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractMessageProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractMessage_);
+              abstractMessage_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+              msgs_ = new java.util.ArrayList<com.google.protobuf.Any>();
+              mutable_bitField0_ |= 0x00000002;
+            }
+            msgs_.add(
+                input.readMessage(com.google.protobuf.Any.parser(), extensionRegistry));
+            break;
+          }
+          case 24: {
+            if (!((mutable_bitField0_ & 0x00000004) != 0)) {
+              msgIds_ = newIntList();
+              mutable_bitField0_ |= 0x00000004;
+            }
+            msgIds_.addInt(input.readInt32());
+            break;
+          }
+          case 26: {
+            int length = input.readRawVarint32();
+            int limit = input.pushLimit(length);
+            if (!((mutable_bitField0_ & 0x00000004) != 0) && input.getBytesUntilLimit() > 0) {
+              msgIds_ = newIntList();
+              mutable_bitField0_ |= 0x00000004;
+            }
+            while (input.getBytesUntilLimit() > 0) {
+              msgIds_.addInt(input.readInt32());
+            }
+            input.popLimit(limit);
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000002) != 0)) {
+        msgs_ = java.util.Collections.unmodifiableList(msgs_);
+      }
+      if (((mutable_bitField0_ & 0x00000004) != 0)) {
+        msgIds_.makeImmutable(); // C
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.MergedWarpMessage.internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.MergedWarpMessage.internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.MergedWarpMessageProto.class, io.seata.codec.protobuf.generated.MergedWarpMessageProto.Builder.class);
+  }
+
+  private int bitField0_;
+  public static final int ABSTRACTMESSAGE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public boolean hasAbstractMessage() {
+    return abstractMessage_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+    return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+    return getAbstractMessage();
+  }
+
+  public static final int MSGS_FIELD_NUMBER = 2;
+  private java.util.List<com.google.protobuf.Any> msgs_;
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public java.util.List<com.google.protobuf.Any> getMsgsList() {
+    return msgs_;
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+      getMsgsOrBuilderList() {
+    return msgs_;
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public int getMsgsCount() {
+    return msgs_.size();
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public com.google.protobuf.Any getMsgs(int index) {
+    return msgs_.get(index);
+  }
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  public com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+      int index) {
+    return msgs_.get(index);
+  }
+
+  public static final int MSGIDS_FIELD_NUMBER = 3;
+  private com.google.protobuf.Internal.IntList msgIds_;
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  public java.util.List<java.lang.Integer>
+      getMsgIdsList() {
+    return msgIds_;
+  }
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  public int getMsgIdsCount() {
+    return msgIds_.size();
+  }
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  public int getMsgIds(int index) {
+    return msgIds_.getInt(index);
+  }
+  private int msgIdsMemoizedSerializedSize = -1;
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    getSerializedSize();
+    if (abstractMessage_ != null) {
+      output.writeMessage(1, getAbstractMessage());
+    }
+    for (int i = 0; i < msgs_.size(); i++) {
+      output.writeMessage(2, msgs_.get(i));
+    }
+    if (getMsgIdsList().size() > 0) {
+      output.writeUInt32NoTag(26);
+      output.writeUInt32NoTag(msgIdsMemoizedSerializedSize);
+    }
+    for (int i = 0; i < msgIds_.size(); i++) {
+      output.writeInt32NoTag(msgIds_.getInt(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractMessage_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractMessage());
+    }
+    for (int i = 0; i < msgs_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, msgs_.get(i));
+    }
+    {
+      int dataSize = 0;
+      for (int i = 0; i < msgIds_.size(); i++) {
+        dataSize += com.google.protobuf.CodedOutputStream
+          .computeInt32SizeNoTag(msgIds_.getInt(i));
+      }
+      size += dataSize;
+      if (!getMsgIdsList().isEmpty()) {
+        size += 1;
+        size += com.google.protobuf.CodedOutputStream
+            .computeInt32SizeNoTag(dataSize);
+      }
+      msgIdsMemoizedSerializedSize = dataSize;
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.MergedWarpMessageProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.MergedWarpMessageProto other = (io.seata.codec.protobuf.generated.MergedWarpMessageProto) obj;
+
+    if (hasAbstractMessage() != other.hasAbstractMessage()) return false;
+    if (hasAbstractMessage()) {
+      if (!getAbstractMessage()
+          .equals(other.getAbstractMessage())) return false;
+    }
+    if (!getMsgsList()
+        .equals(other.getMsgsList())) return false;
+    if (!getMsgIdsList()
+        .equals(other.getMsgIdsList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractMessage()) {
+      hash = (37 * hash) + ABSTRACTMESSAGE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractMessage().hashCode();
+    }
+    if (getMsgsCount() > 0) {
+      hash = (37 * hash) + MSGS_FIELD_NUMBER;
+      hash = (53 * hash) + getMsgsList().hashCode();
+    }
+    if (getMsgIdsCount() > 0) {
+      hash = (37 * hash) + MSGIDS_FIELD_NUMBER;
+      hash = (53 * hash) + getMsgIdsList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.MergedWarpMessageProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.MergedWarpMessageProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.MergedWarpMessageProto)
+      io.seata.codec.protobuf.generated.MergedWarpMessageProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.MergedWarpMessage.internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.MergedWarpMessage.internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.MergedWarpMessageProto.class, io.seata.codec.protobuf.generated.MergedWarpMessageProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.MergedWarpMessageProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getMsgsFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+      if (msgsBuilder_ == null) {
+        msgs_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+      } else {
+        msgsBuilder_.clear();
+      }
+      msgIds_ = emptyIntList();
+      bitField0_ = (bitField0_ & ~0x00000004);
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.MergedWarpMessage.internal_static_io_seata_protocol_protobuf_MergedWarpMessageProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedWarpMessageProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.MergedWarpMessageProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedWarpMessageProto build() {
+      io.seata.codec.protobuf.generated.MergedWarpMessageProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.MergedWarpMessageProto buildPartial() {
+      io.seata.codec.protobuf.generated.MergedWarpMessageProto result = new io.seata.codec.protobuf.generated.MergedWarpMessageProto(this);
+      int from_bitField0_ = bitField0_;
+      int to_bitField0_ = 0;
+      if (abstractMessageBuilder_ == null) {
+        result.abstractMessage_ = abstractMessage_;
+      } else {
+        result.abstractMessage_ = abstractMessageBuilder_.build();
+      }
+      if (msgsBuilder_ == null) {
+        if (((bitField0_ & 0x00000002) != 0)) {
+          msgs_ = java.util.Collections.unmodifiableList(msgs_);
+          bitField0_ = (bitField0_ & ~0x00000002);
+        }
+        result.msgs_ = msgs_;
+      } else {
+        result.msgs_ = msgsBuilder_.build();
+      }
+      if (((bitField0_ & 0x00000004) != 0)) {
+        msgIds_.makeImmutable();
+        bitField0_ = (bitField0_ & ~0x00000004);
+      }
+      result.msgIds_ = msgIds_;
+      result.bitField0_ = to_bitField0_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.MergedWarpMessageProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.MergedWarpMessageProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.MergedWarpMessageProto other) {
+      if (other == io.seata.codec.protobuf.generated.MergedWarpMessageProto.getDefaultInstance()) return this;
+      if (other.hasAbstractMessage()) {
+        mergeAbstractMessage(other.getAbstractMessage());
+      }
+      if (msgsBuilder_ == null) {
+        if (!other.msgs_.isEmpty()) {
+          if (msgs_.isEmpty()) {
+            msgs_ = other.msgs_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+          } else {
+            ensureMsgsIsMutable();
+            msgs_.addAll(other.msgs_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.msgs_.isEmpty()) {
+          if (msgsBuilder_.isEmpty()) {
+            msgsBuilder_.dispose();
+            msgsBuilder_ = null;
+            msgs_ = other.msgs_;
+            bitField0_ = (bitField0_ & ~0x00000002);
+            msgsBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getMsgsFieldBuilder() : null;
+          } else {
+            msgsBuilder_.addAllMessages(other.msgs_);
+          }
+        }
+      }
+      if (!other.msgIds_.isEmpty()) {
+        if (msgIds_.isEmpty()) {
+          msgIds_ = other.msgIds_;
+          bitField0_ = (bitField0_ & ~0x00000004);
+        } else {
+          ensureMsgIdsIsMutable();
+          msgIds_.addAll(other.msgIds_);
+        }
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.MergedWarpMessageProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.MergedWarpMessageProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private io.seata.codec.protobuf.generated.AbstractMessageProto abstractMessage_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> abstractMessageBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public boolean hasAbstractMessage() {
+      return abstractMessageBuilder_ != null || abstractMessage_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        return abstractMessage_ == null ? io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      } else {
+        return abstractMessageBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractMessage_ = value;
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder setAbstractMessage(
+        io.seata.codec.protobuf.generated.AbstractMessageProto.Builder builderForValue) {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractMessageBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder mergeAbstractMessage(io.seata.codec.protobuf.generated.AbstractMessageProto value) {
+      if (abstractMessageBuilder_ == null) {
+        if (abstractMessage_ != null) {
+          abstractMessage_ =
+            io.seata.codec.protobuf.generated.AbstractMessageProto.newBuilder(abstractMessage_).mergeFrom(value).buildPartial();
+        } else {
+          abstractMessage_ = value;
+        }
+        onChanged();
+      } else {
+        abstractMessageBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public Builder clearAbstractMessage() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessage_ = null;
+        onChanged();
+      } else {
+        abstractMessage_ = null;
+        abstractMessageBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProto.Builder getAbstractMessageBuilder() {
+      
+      onChanged();
+      return getAbstractMessageFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder() {
+      if (abstractMessageBuilder_ != null) {
+        return abstractMessageBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractMessage_ == null ?
+            io.seata.codec.protobuf.generated.AbstractMessageProto.getDefaultInstance() : abstractMessage_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder> 
+        getAbstractMessageFieldBuilder() {
+      if (abstractMessageBuilder_ == null) {
+        abstractMessageBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractMessageProto, io.seata.codec.protobuf.generated.AbstractMessageProto.Builder, io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder>(
+                getAbstractMessage(),
+                getParentForChildren(),
+                isClean());
+        abstractMessage_ = null;
+      }
+      return abstractMessageBuilder_;
+    }
+
+    private java.util.List<com.google.protobuf.Any> msgs_ =
+      java.util.Collections.emptyList();
+    private void ensureMsgsIsMutable() {
+      if (!((bitField0_ & 0x00000002) != 0)) {
+        msgs_ = new java.util.ArrayList<com.google.protobuf.Any>(msgs_);
+        bitField0_ |= 0x00000002;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> msgsBuilder_;
+
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<com.google.protobuf.Any> getMsgsList() {
+      if (msgsBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(msgs_);
+      } else {
+        return msgsBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public int getMsgsCount() {
+      if (msgsBuilder_ == null) {
+        return msgs_.size();
+      } else {
+        return msgsBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any getMsgs(int index) {
+      if (msgsBuilder_ == null) {
+        return msgs_.get(index);
+      } else {
+        return msgsBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder setMsgs(
+        int index, com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.set(index, value);
+        onChanged();
+      } else {
+        msgsBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder setMsgs(
+        int index, com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.add(value);
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        int index, com.google.protobuf.Any value) {
+      if (msgsBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureMsgsIsMutable();
+        msgs_.add(index, value);
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.add(builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addMsgs(
+        int index, com.google.protobuf.Any.Builder builderForValue) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        msgsBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder addAllMsgs(
+        java.lang.Iterable<? extends com.google.protobuf.Any> values) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, msgs_);
+        onChanged();
+      } else {
+        msgsBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder clearMsgs() {
+      if (msgsBuilder_ == null) {
+        msgs_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000002);
+        onChanged();
+      } else {
+        msgsBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public Builder removeMsgs(int index) {
+      if (msgsBuilder_ == null) {
+        ensureMsgsIsMutable();
+        msgs_.remove(index);
+        onChanged();
+      } else {
+        msgsBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder getMsgsBuilder(
+        int index) {
+      return getMsgsFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+        int index) {
+      if (msgsBuilder_ == null) {
+        return msgs_.get(index);  } else {
+        return msgsBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+         getMsgsOrBuilderList() {
+      if (msgsBuilder_ != null) {
+        return msgsBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(msgs_);
+      }
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder addMsgsBuilder() {
+      return getMsgsFieldBuilder().addBuilder(
+          com.google.protobuf.Any.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public com.google.protobuf.Any.Builder addMsgsBuilder(
+        int index) {
+      return getMsgsFieldBuilder().addBuilder(
+          index, com.google.protobuf.Any.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .google.protobuf.Any msgs = 2;</code>
+     */
+    public java.util.List<com.google.protobuf.Any.Builder> 
+         getMsgsBuilderList() {
+      return getMsgsFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder> 
+        getMsgsFieldBuilder() {
+      if (msgsBuilder_ == null) {
+        msgsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            com.google.protobuf.Any, com.google.protobuf.Any.Builder, com.google.protobuf.AnyOrBuilder>(
+                msgs_,
+                ((bitField0_ & 0x00000002) != 0),
+                getParentForChildren(),
+                isClean());
+        msgs_ = null;
+      }
+      return msgsBuilder_;
+    }
+
+    private com.google.protobuf.Internal.IntList msgIds_ = emptyIntList();
+    private void ensureMsgIdsIsMutable() {
+      if (!((bitField0_ & 0x00000004) != 0)) {
+        msgIds_ = mutableCopy(msgIds_);
+        bitField0_ |= 0x00000004;
+       }
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public java.util.List<java.lang.Integer>
+        getMsgIdsList() {
+      return ((bitField0_ & 0x00000004) != 0) ?
+               java.util.Collections.unmodifiableList(msgIds_) : msgIds_;
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public int getMsgIdsCount() {
+      return msgIds_.size();
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public int getMsgIds(int index) {
+      return msgIds_.getInt(index);
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public Builder setMsgIds(
+        int index, int value) {
+      ensureMsgIdsIsMutable();
+      msgIds_.setInt(index, value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public Builder addMsgIds(int value) {
+      ensureMsgIdsIsMutable();
+      msgIds_.addInt(value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public Builder addAllMsgIds(
+        java.lang.Iterable<? extends java.lang.Integer> values) {
+      ensureMsgIdsIsMutable();
+      com.google.protobuf.AbstractMessageLite.Builder.addAll(
+          values, msgIds_);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated int32 msgIds = 3;</code>
+     */
+    public Builder clearMsgIds() {
+      msgIds_ = emptyIntList();
+      bitField0_ = (bitField0_ & ~0x00000004);
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.MergedWarpMessageProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.MergedWarpMessageProto)
+  private static final io.seata.codec.protobuf.generated.MergedWarpMessageProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.MergedWarpMessageProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.MergedWarpMessageProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<MergedWarpMessageProto>
+      PARSER = new com.google.protobuf.AbstractParser<MergedWarpMessageProto>() {
+    @java.lang.Override
+    public MergedWarpMessageProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new MergedWarpMessageProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<MergedWarpMessageProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<MergedWarpMessageProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.MergedWarpMessageProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..dde68138a89ba8b95dd4f578499ead9533c3a9ac
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MergedWarpMessageProtoOrBuilder.java
@@ -0,0 +1,59 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: mergedWarpMessage.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface MergedWarpMessageProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.MergedWarpMessageProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  boolean hasAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProto getAbstractMessage();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractMessageProto abstractMessage = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractMessageProtoOrBuilder getAbstractMessageOrBuilder();
+
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  java.util.List<com.google.protobuf.Any> 
+      getMsgsList();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  com.google.protobuf.Any getMsgs(int index);
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  int getMsgsCount();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  java.util.List<? extends com.google.protobuf.AnyOrBuilder> 
+      getMsgsOrBuilderList();
+  /**
+   * <code>repeated .google.protobuf.Any msgs = 2;</code>
+   */
+  com.google.protobuf.AnyOrBuilder getMsgsOrBuilder(
+      int index);
+
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  java.util.List<java.lang.Integer> getMsgIdsList();
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  int getMsgIdsCount();
+  /**
+   * <code>repeated int32 msgIds = 3;</code>
+   */
+  int getMsgIds(int index);
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageType.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageType.java
new file mode 100644
index 0000000000000000000000000000000000000000..0960e84b64edebb034fd9b1023c073d0eb69de75
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageType.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: messageType.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class MessageType {
+  private MessageType() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\021messageType.proto\022\032io.seata.protocol.p" +
+      "rotobuf*\303\005\n\020MessageTypeProto\022\031\n\025TYPE_GLO" +
+      "BAL_PRESERVED\020\000\022\025\n\021TYPE_GLOBAL_BEGIN\020\001\022\034" +
+      "\n\030TYPE_GLOBAL_BEGIN_RESULT\020\002\022\026\n\022TYPE_GLO" +
+      "BAL_COMMIT\020\007\022\035\n\031TYPE_GLOBAL_COMMIT_RESUL" +
+      "T\020\010\022\030\n\024TYPE_GLOBAL_ROLLBACK\020\t\022\037\n\033TYPE_GL" +
+      "OBAL_ROLLBACK_RESULT\020\n\022\026\n\022TYPE_GLOBAL_ST" +
+      "ATUS\020\017\022\035\n\031TYPE_GLOBAL_STATUS_RESULT\020\020\022\032\n" +
+      "\026TYPE_GLOBAL_LOCK_QUERY\020\025\022!\n\035TYPE_GLOBAL" +
+      "_LOCK_QUERY_RESULT\020\026\022\026\n\022TYPE_BRANCH_COMM" +
+      "IT\020\003\022\035\n\031TYPE_BRANCH_COMMIT_RESULT\020\004\022\030\n\024T" +
+      "YPE_BRANCH_ROLLBACK\020\005\022\037\n\033TYPE_BRANCH_ROL" +
+      "LBACK_RESULT\020\006\022\030\n\024TYPE_BRANCH_REGISTER\020\013" +
+      "\022\037\n\033TYPE_BRANCH_REGISTER_RESULT\020\014\022\035\n\031TYP" +
+      "E_BRANCH_STATUS_REPORT\020\r\022$\n TYPE_BRANCH_" +
+      "STATUS_REPORT_RESULT\020\016\022\024\n\020TYPE_SEATA_MER" +
+      "GE\020;\022\033\n\027TYPE_SEATA_MERGE_RESULT\020<\022\020\n\014TYP" +
+      "E_REG_CLT\020e\022\027\n\023TYPE_REG_CLT_RESULT\020f\022\017\n\013" +
+      "TYPE_REG_RM\020g\022\026\n\022TYPE_REG_RM_RESULT\020hB2\n" +
+      "!io.seata.codec.protobuf.generatedB\013Mess" +
+      "ageTypeP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageTypeProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageTypeProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..f943b62386d425c8e95fd6ce67dacaacfb897a2a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/MessageTypeProto.java
@@ -0,0 +1,534 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: messageType.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.MessageTypeProto}
+ */
+public enum MessageTypeProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <code>TYPE_GLOBAL_PRESERVED = 0;</code>
+   */
+  TYPE_GLOBAL_PRESERVED(0),
+  /**
+   * <code>TYPE_GLOBAL_BEGIN = 1;</code>
+   */
+  TYPE_GLOBAL_BEGIN(1),
+  /**
+   * <code>TYPE_GLOBAL_BEGIN_RESULT = 2;</code>
+   */
+  TYPE_GLOBAL_BEGIN_RESULT(2),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_COMMIT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_COMMIT = 7;</code>
+   */
+  TYPE_GLOBAL_COMMIT(7),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_COMMIT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_COMMIT_RESULT = 8;</code>
+   */
+  TYPE_GLOBAL_COMMIT_RESULT(8),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_ROLLBACK.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_ROLLBACK = 9;</code>
+   */
+  TYPE_GLOBAL_ROLLBACK(9),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_ROLLBACK_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_ROLLBACK_RESULT = 10;</code>
+   */
+  TYPE_GLOBAL_ROLLBACK_RESULT(10),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_STATUS.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_STATUS = 15;</code>
+   */
+  TYPE_GLOBAL_STATUS(15),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_STATUS_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_STATUS_RESULT = 16;</code>
+   */
+  TYPE_GLOBAL_STATUS_RESULT(16),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_LOCK_QUERY.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_LOCK_QUERY = 21;</code>
+   */
+  TYPE_GLOBAL_LOCK_QUERY(21),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_LOCK_QUERY_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_LOCK_QUERY_RESULT = 22;</code>
+   */
+  TYPE_GLOBAL_LOCK_QUERY_RESULT(22),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_COMMIT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_COMMIT = 3;</code>
+   */
+  TYPE_BRANCH_COMMIT(3),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_COMMIT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_COMMIT_RESULT = 4;</code>
+   */
+  TYPE_BRANCH_COMMIT_RESULT(4),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_ROLLBACK.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_ROLLBACK = 5;</code>
+   */
+  TYPE_BRANCH_ROLLBACK(5),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_ROLLBACK_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_ROLLBACK_RESULT = 6;</code>
+   */
+  TYPE_BRANCH_ROLLBACK_RESULT(6),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_REGISTER.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_REGISTER = 11;</code>
+   */
+  TYPE_BRANCH_REGISTER(11),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_REGISTER_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_REGISTER_RESULT = 12;</code>
+   */
+  TYPE_BRANCH_REGISTER_RESULT(12),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_STATUS_REPORT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_STATUS_REPORT = 13;</code>
+   */
+  TYPE_BRANCH_STATUS_REPORT(13),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_STATUS_REPORT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_STATUS_REPORT_RESULT = 14;</code>
+   */
+  TYPE_BRANCH_STATUS_REPORT_RESULT(14),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_SEATA_MERGE.
+   * </pre>
+   *
+   * <code>TYPE_SEATA_MERGE = 59;</code>
+   */
+  TYPE_SEATA_MERGE(59),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_SEATA_MERGE_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_SEATA_MERGE_RESULT = 60;</code>
+   */
+  TYPE_SEATA_MERGE_RESULT(60),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_CLT.
+   * </pre>
+   *
+   * <code>TYPE_REG_CLT = 101;</code>
+   */
+  TYPE_REG_CLT(101),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_CLT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_REG_CLT_RESULT = 102;</code>
+   */
+  TYPE_REG_CLT_RESULT(102),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_RM.
+   * </pre>
+   *
+   * <code>TYPE_REG_RM = 103;</code>
+   */
+  TYPE_REG_RM(103),
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_RM_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_REG_RM_RESULT = 104;</code>
+   */
+  TYPE_REG_RM_RESULT(104),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <code>TYPE_GLOBAL_PRESERVED = 0;</code>
+   */
+  public static final int TYPE_GLOBAL_PRESERVED_VALUE = 0;
+  /**
+   * <code>TYPE_GLOBAL_BEGIN = 1;</code>
+   */
+  public static final int TYPE_GLOBAL_BEGIN_VALUE = 1;
+  /**
+   * <code>TYPE_GLOBAL_BEGIN_RESULT = 2;</code>
+   */
+  public static final int TYPE_GLOBAL_BEGIN_RESULT_VALUE = 2;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_COMMIT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_COMMIT = 7;</code>
+   */
+  public static final int TYPE_GLOBAL_COMMIT_VALUE = 7;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_COMMIT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_COMMIT_RESULT = 8;</code>
+   */
+  public static final int TYPE_GLOBAL_COMMIT_RESULT_VALUE = 8;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_ROLLBACK.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_ROLLBACK = 9;</code>
+   */
+  public static final int TYPE_GLOBAL_ROLLBACK_VALUE = 9;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_ROLLBACK_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_ROLLBACK_RESULT = 10;</code>
+   */
+  public static final int TYPE_GLOBAL_ROLLBACK_RESULT_VALUE = 10;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_STATUS.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_STATUS = 15;</code>
+   */
+  public static final int TYPE_GLOBAL_STATUS_VALUE = 15;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_STATUS_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_STATUS_RESULT = 16;</code>
+   */
+  public static final int TYPE_GLOBAL_STATUS_RESULT_VALUE = 16;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_LOCK_QUERY.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_LOCK_QUERY = 21;</code>
+   */
+  public static final int TYPE_GLOBAL_LOCK_QUERY_VALUE = 21;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_GLOBAL_LOCK_QUERY_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_GLOBAL_LOCK_QUERY_RESULT = 22;</code>
+   */
+  public static final int TYPE_GLOBAL_LOCK_QUERY_RESULT_VALUE = 22;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_COMMIT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_COMMIT = 3;</code>
+   */
+  public static final int TYPE_BRANCH_COMMIT_VALUE = 3;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_COMMIT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_COMMIT_RESULT = 4;</code>
+   */
+  public static final int TYPE_BRANCH_COMMIT_RESULT_VALUE = 4;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_ROLLBACK.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_ROLLBACK = 5;</code>
+   */
+  public static final int TYPE_BRANCH_ROLLBACK_VALUE = 5;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_ROLLBACK_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_ROLLBACK_RESULT = 6;</code>
+   */
+  public static final int TYPE_BRANCH_ROLLBACK_RESULT_VALUE = 6;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_REGISTER.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_REGISTER = 11;</code>
+   */
+  public static final int TYPE_BRANCH_REGISTER_VALUE = 11;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_REGISTER_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_REGISTER_RESULT = 12;</code>
+   */
+  public static final int TYPE_BRANCH_REGISTER_RESULT_VALUE = 12;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_STATUS_REPORT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_STATUS_REPORT = 13;</code>
+   */
+  public static final int TYPE_BRANCH_STATUS_REPORT_VALUE = 13;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_BRANCH_STATUS_REPORT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_BRANCH_STATUS_REPORT_RESULT = 14;</code>
+   */
+  public static final int TYPE_BRANCH_STATUS_REPORT_RESULT_VALUE = 14;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_SEATA_MERGE.
+   * </pre>
+   *
+   * <code>TYPE_SEATA_MERGE = 59;</code>
+   */
+  public static final int TYPE_SEATA_MERGE_VALUE = 59;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_SEATA_MERGE_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_SEATA_MERGE_RESULT = 60;</code>
+   */
+  public static final int TYPE_SEATA_MERGE_RESULT_VALUE = 60;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_CLT.
+   * </pre>
+   *
+   * <code>TYPE_REG_CLT = 101;</code>
+   */
+  public static final int TYPE_REG_CLT_VALUE = 101;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_CLT_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_REG_CLT_RESULT = 102;</code>
+   */
+  public static final int TYPE_REG_CLT_RESULT_VALUE = 102;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_RM.
+   * </pre>
+   *
+   * <code>TYPE_REG_RM = 103;</code>
+   */
+  public static final int TYPE_REG_RM_VALUE = 103;
+  /**
+   * <pre>
+   **
+   * The constant TYPE_REG_RM_RESULT.
+   * </pre>
+   *
+   * <code>TYPE_REG_RM_RESULT = 104;</code>
+   */
+  public static final int TYPE_REG_RM_RESULT_VALUE = 104;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static MessageTypeProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static MessageTypeProto forNumber(int value) {
+    switch (value) {
+      case 0: return TYPE_GLOBAL_PRESERVED;
+      case 1: return TYPE_GLOBAL_BEGIN;
+      case 2: return TYPE_GLOBAL_BEGIN_RESULT;
+      case 7: return TYPE_GLOBAL_COMMIT;
+      case 8: return TYPE_GLOBAL_COMMIT_RESULT;
+      case 9: return TYPE_GLOBAL_ROLLBACK;
+      case 10: return TYPE_GLOBAL_ROLLBACK_RESULT;
+      case 15: return TYPE_GLOBAL_STATUS;
+      case 16: return TYPE_GLOBAL_STATUS_RESULT;
+      case 21: return TYPE_GLOBAL_LOCK_QUERY;
+      case 22: return TYPE_GLOBAL_LOCK_QUERY_RESULT;
+      case 3: return TYPE_BRANCH_COMMIT;
+      case 4: return TYPE_BRANCH_COMMIT_RESULT;
+      case 5: return TYPE_BRANCH_ROLLBACK;
+      case 6: return TYPE_BRANCH_ROLLBACK_RESULT;
+      case 11: return TYPE_BRANCH_REGISTER;
+      case 12: return TYPE_BRANCH_REGISTER_RESULT;
+      case 13: return TYPE_BRANCH_STATUS_REPORT;
+      case 14: return TYPE_BRANCH_STATUS_REPORT_RESULT;
+      case 59: return TYPE_SEATA_MERGE;
+      case 60: return TYPE_SEATA_MERGE_RESULT;
+      case 101: return TYPE_REG_CLT;
+      case 102: return TYPE_REG_CLT_RESULT;
+      case 103: return TYPE_REG_RM;
+      case 104: return TYPE_REG_RM_RESULT;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<MessageTypeProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      MessageTypeProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<MessageTypeProto>() {
+          public MessageTypeProto findValueByNumber(int number) {
+            return MessageTypeProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.MessageType.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final MessageTypeProto[] VALUES = values();
+
+  public static MessageTypeProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private MessageTypeProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.MessageTypeProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3b126786c2c2a5e8bebd2d4adb3a473706e427c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequest.java
@@ -0,0 +1,63 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class RegisterRMRequest {
+  private RegisterRMRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\027registerRMRequest.proto\022\032io.seata.prot" +
+      "ocol.protobuf\032\035abstractIdentifyRequest.p" +
+      "roto\"\210\001\n\026RegisterRMRequestProto\022Y\n\027abstr" +
+      "actIdentifyRequest\030\001 \001(\01328.io.seata.prot" +
+      "ocol.protobuf.AbstractIdentifyRequestPro" +
+      "to\022\023\n\013resourceIds\030\002 \001(\tB8\n!io.seata.code" +
+      "c.protobuf.generatedB\021RegisterRMRequestP" +
+      "\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractIdentifyRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor,
+        new java.lang.String[] { "AbstractIdentifyRequest", "ResourceIds", });
+    io.seata.codec.protobuf.generated.AbstractIdentifyRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..b78713e8989f912bec0d55ac2ede8bd25610565f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProto.java
@@ -0,0 +1,729 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.RegisterRMRequestProto}
+ */
+public  final class RegisterRMRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.RegisterRMRequestProto)
+    RegisterRMRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RegisterRMRequestProto.newBuilder() to construct.
+  private RegisterRMRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RegisterRMRequestProto() {
+    resourceIds_ = "";
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RegisterRMRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder subBuilder = null;
+            if (abstractIdentifyRequest_ != null) {
+              subBuilder = abstractIdentifyRequest_.toBuilder();
+            }
+            abstractIdentifyRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractIdentifyRequest_);
+              abstractIdentifyRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            resourceIds_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.RegisterRMRequest.internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.RegisterRMRequest.internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.RegisterRMRequestProto.class, io.seata.codec.protobuf.generated.RegisterRMRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTIDENTIFYREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto abstractIdentifyRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public boolean hasAbstractIdentifyRequest() {
+    return abstractIdentifyRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest() {
+    return abstractIdentifyRequest_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder() {
+    return getAbstractIdentifyRequest();
+  }
+
+  public static final int RESOURCEIDS_FIELD_NUMBER = 2;
+  private volatile java.lang.Object resourceIds_;
+  /**
+   * <code>string resourceIds = 2;</code>
+   */
+  public java.lang.String getResourceIds() {
+    java.lang.Object ref = resourceIds_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      resourceIds_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string resourceIds = 2;</code>
+   */
+  public com.google.protobuf.ByteString
+      getResourceIdsBytes() {
+    java.lang.Object ref = resourceIds_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      resourceIds_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractIdentifyRequest_ != null) {
+      output.writeMessage(1, getAbstractIdentifyRequest());
+    }
+    if (!getResourceIdsBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, resourceIds_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractIdentifyRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractIdentifyRequest());
+    }
+    if (!getResourceIdsBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, resourceIds_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.RegisterRMRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.RegisterRMRequestProto other = (io.seata.codec.protobuf.generated.RegisterRMRequestProto) obj;
+
+    if (hasAbstractIdentifyRequest() != other.hasAbstractIdentifyRequest()) return false;
+    if (hasAbstractIdentifyRequest()) {
+      if (!getAbstractIdentifyRequest()
+          .equals(other.getAbstractIdentifyRequest())) return false;
+    }
+    if (!getResourceIds()
+        .equals(other.getResourceIds())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractIdentifyRequest()) {
+      hash = (37 * hash) + ABSTRACTIDENTIFYREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractIdentifyRequest().hashCode();
+    }
+    hash = (37 * hash) + RESOURCEIDS_FIELD_NUMBER;
+    hash = (53 * hash) + getResourceIds().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.RegisterRMRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.RegisterRMRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.RegisterRMRequestProto)
+      io.seata.codec.protobuf.generated.RegisterRMRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.RegisterRMRequest.internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.RegisterRMRequest.internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.RegisterRMRequestProto.class, io.seata.codec.protobuf.generated.RegisterRMRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.RegisterRMRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = null;
+      } else {
+        abstractIdentifyRequest_ = null;
+        abstractIdentifyRequestBuilder_ = null;
+      }
+      resourceIds_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.RegisterRMRequest.internal_static_io_seata_protocol_protobuf_RegisterRMRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.RegisterRMRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMRequestProto build() {
+      io.seata.codec.protobuf.generated.RegisterRMRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.RegisterRMRequestProto result = new io.seata.codec.protobuf.generated.RegisterRMRequestProto(this);
+      if (abstractIdentifyRequestBuilder_ == null) {
+        result.abstractIdentifyRequest_ = abstractIdentifyRequest_;
+      } else {
+        result.abstractIdentifyRequest_ = abstractIdentifyRequestBuilder_.build();
+      }
+      result.resourceIds_ = resourceIds_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.RegisterRMRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.RegisterRMRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.RegisterRMRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.RegisterRMRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractIdentifyRequest()) {
+        mergeAbstractIdentifyRequest(other.getAbstractIdentifyRequest());
+      }
+      if (!other.getResourceIds().isEmpty()) {
+        resourceIds_ = other.resourceIds_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.RegisterRMRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.RegisterRMRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto abstractIdentifyRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder> abstractIdentifyRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public boolean hasAbstractIdentifyRequest() {
+      return abstractIdentifyRequestBuilder_ != null || abstractIdentifyRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        return abstractIdentifyRequest_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+      } else {
+        return abstractIdentifyRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder setAbstractIdentifyRequest(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto value) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractIdentifyRequest_ = value;
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder setAbstractIdentifyRequest(
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder builderForValue) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder mergeAbstractIdentifyRequest(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto value) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        if (abstractIdentifyRequest_ != null) {
+          abstractIdentifyRequest_ =
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.newBuilder(abstractIdentifyRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractIdentifyRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder clearAbstractIdentifyRequest() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = null;
+        onChanged();
+      } else {
+        abstractIdentifyRequest_ = null;
+        abstractIdentifyRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder getAbstractIdentifyRequestBuilder() {
+      
+      onChanged();
+      return getAbstractIdentifyRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder() {
+      if (abstractIdentifyRequestBuilder_ != null) {
+        return abstractIdentifyRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractIdentifyRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder> 
+        getAbstractIdentifyRequestFieldBuilder() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder>(
+                getAbstractIdentifyRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractIdentifyRequest_ = null;
+      }
+      return abstractIdentifyRequestBuilder_;
+    }
+
+    private java.lang.Object resourceIds_ = "";
+    /**
+     * <code>string resourceIds = 2;</code>
+     */
+    public java.lang.String getResourceIds() {
+      java.lang.Object ref = resourceIds_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        resourceIds_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string resourceIds = 2;</code>
+     */
+    public com.google.protobuf.ByteString
+        getResourceIdsBytes() {
+      java.lang.Object ref = resourceIds_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        resourceIds_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string resourceIds = 2;</code>
+     */
+    public Builder setResourceIds(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      resourceIds_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceIds = 2;</code>
+     */
+    public Builder clearResourceIds() {
+      
+      resourceIds_ = getDefaultInstance().getResourceIds();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string resourceIds = 2;</code>
+     */
+    public Builder setResourceIdsBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      resourceIds_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.RegisterRMRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.RegisterRMRequestProto)
+  private static final io.seata.codec.protobuf.generated.RegisterRMRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.RegisterRMRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterRMRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RegisterRMRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<RegisterRMRequestProto>() {
+    @java.lang.Override
+    public RegisterRMRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RegisterRMRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RegisterRMRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RegisterRMRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.RegisterRMRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..4ccc81ea232074a328b049d8b897f0ccf756ad06
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMRequestProtoOrBuilder.java
@@ -0,0 +1,32 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface RegisterRMRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.RegisterRMRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  boolean hasAbstractIdentifyRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder();
+
+  /**
+   * <code>string resourceIds = 2;</code>
+   */
+  java.lang.String getResourceIds();
+  /**
+   * <code>string resourceIds = 2;</code>
+   */
+  com.google.protobuf.ByteString
+      getResourceIdsBytes();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..53a22239123179938816c2c05c0555abfaed2630
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponse.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class RegisterRMResponse {
+  private RegisterRMResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\030registerRMResponse.proto\022\032io.seata.pro" +
+      "tocol.protobuf\032\036abstractIdentifyResponse" +
+      ".proto\"v\n\027RegisterRMResponseProto\022[\n\030abs" +
+      "tractIdentifyResponse\030\001 \001(\01329.io.seata.p" +
+      "rotocol.protobuf.AbstractIdentifyRespons" +
+      "eProtoB9\n!io.seata.codec.protobuf.genera" +
+      "tedB\022RegisterRMResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractIdentifyResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor,
+        new java.lang.String[] { "AbstractIdentifyResponse", });
+    io.seata.codec.protobuf.generated.AbstractIdentifyResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..30a622295d404ca8c6f2fe7642a0c59634913f09
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.RegisterRMResponseProto}
+ */
+public  final class RegisterRMResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.RegisterRMResponseProto)
+    RegisterRMResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RegisterRMResponseProto.newBuilder() to construct.
+  private RegisterRMResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RegisterRMResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RegisterRMResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder subBuilder = null;
+            if (abstractIdentifyResponse_ != null) {
+              subBuilder = abstractIdentifyResponse_.toBuilder();
+            }
+            abstractIdentifyResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractIdentifyResponse_);
+              abstractIdentifyResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.RegisterRMResponse.internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.RegisterRMResponse.internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.RegisterRMResponseProto.class, io.seata.codec.protobuf.generated.RegisterRMResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTIDENTIFYRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto abstractIdentifyResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public boolean hasAbstractIdentifyResponse() {
+    return abstractIdentifyResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse() {
+    return abstractIdentifyResponse_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder() {
+    return getAbstractIdentifyResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractIdentifyResponse_ != null) {
+      output.writeMessage(1, getAbstractIdentifyResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractIdentifyResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractIdentifyResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.RegisterRMResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.RegisterRMResponseProto other = (io.seata.codec.protobuf.generated.RegisterRMResponseProto) obj;
+
+    if (hasAbstractIdentifyResponse() != other.hasAbstractIdentifyResponse()) return false;
+    if (hasAbstractIdentifyResponse()) {
+      if (!getAbstractIdentifyResponse()
+          .equals(other.getAbstractIdentifyResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractIdentifyResponse()) {
+      hash = (37 * hash) + ABSTRACTIDENTIFYRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractIdentifyResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.RegisterRMResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.RegisterRMResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.RegisterRMResponseProto)
+      io.seata.codec.protobuf.generated.RegisterRMResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.RegisterRMResponse.internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.RegisterRMResponse.internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.RegisterRMResponseProto.class, io.seata.codec.protobuf.generated.RegisterRMResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.RegisterRMResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = null;
+      } else {
+        abstractIdentifyResponse_ = null;
+        abstractIdentifyResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.RegisterRMResponse.internal_static_io_seata_protocol_protobuf_RegisterRMResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.RegisterRMResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMResponseProto build() {
+      io.seata.codec.protobuf.generated.RegisterRMResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterRMResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.RegisterRMResponseProto result = new io.seata.codec.protobuf.generated.RegisterRMResponseProto(this);
+      if (abstractIdentifyResponseBuilder_ == null) {
+        result.abstractIdentifyResponse_ = abstractIdentifyResponse_;
+      } else {
+        result.abstractIdentifyResponse_ = abstractIdentifyResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.RegisterRMResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.RegisterRMResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.RegisterRMResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.RegisterRMResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractIdentifyResponse()) {
+        mergeAbstractIdentifyResponse(other.getAbstractIdentifyResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.RegisterRMResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.RegisterRMResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto abstractIdentifyResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder> abstractIdentifyResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public boolean hasAbstractIdentifyResponse() {
+      return abstractIdentifyResponseBuilder_ != null || abstractIdentifyResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        return abstractIdentifyResponse_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+      } else {
+        return abstractIdentifyResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder setAbstractIdentifyResponse(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto value) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractIdentifyResponse_ = value;
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder setAbstractIdentifyResponse(
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder builderForValue) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder mergeAbstractIdentifyResponse(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto value) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        if (abstractIdentifyResponse_ != null) {
+          abstractIdentifyResponse_ =
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.newBuilder(abstractIdentifyResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractIdentifyResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder clearAbstractIdentifyResponse() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = null;
+        onChanged();
+      } else {
+        abstractIdentifyResponse_ = null;
+        abstractIdentifyResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder getAbstractIdentifyResponseBuilder() {
+      
+      onChanged();
+      return getAbstractIdentifyResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder() {
+      if (abstractIdentifyResponseBuilder_ != null) {
+        return abstractIdentifyResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractIdentifyResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder> 
+        getAbstractIdentifyResponseFieldBuilder() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder>(
+                getAbstractIdentifyResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractIdentifyResponse_ = null;
+      }
+      return abstractIdentifyResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.RegisterRMResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.RegisterRMResponseProto)
+  private static final io.seata.codec.protobuf.generated.RegisterRMResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.RegisterRMResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterRMResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RegisterRMResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<RegisterRMResponseProto>() {
+    @java.lang.Override
+    public RegisterRMResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RegisterRMResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RegisterRMResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RegisterRMResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.RegisterRMResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..1cc8319bf479eb61761bc88703876f21b6f71deb
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterRMResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerRMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface RegisterRMResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.RegisterRMResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  boolean hasAbstractIdentifyResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequest.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cff375761f74060a4109ff4bcdba83d5b2a36a9b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequest.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class RegisterTMRequest {
+  private RegisterTMRequest() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\027registerTMRequest.proto\022\032io.seata.prot" +
+      "ocol.protobuf\032\035abstractIdentifyRequest.p" +
+      "roto\"s\n\026RegisterTMRequestProto\022Y\n\027abstra" +
+      "ctIdentifyRequest\030\001 \001(\01328.io.seata.proto" +
+      "col.protobuf.AbstractIdentifyRequestProt" +
+      "oB8\n!io.seata.codec.protobuf.generatedB\021" +
+      "RegisterTMRequestP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractIdentifyRequest.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor,
+        new java.lang.String[] { "AbstractIdentifyRequest", });
+    io.seata.codec.protobuf.generated.AbstractIdentifyRequest.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..36263c6f58a911feccacdffc8972213ca4df8520
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.RegisterTMRequestProto}
+ */
+public  final class RegisterTMRequestProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.RegisterTMRequestProto)
+    RegisterTMRequestProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RegisterTMRequestProto.newBuilder() to construct.
+  private RegisterTMRequestProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RegisterTMRequestProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RegisterTMRequestProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder subBuilder = null;
+            if (abstractIdentifyRequest_ != null) {
+              subBuilder = abstractIdentifyRequest_.toBuilder();
+            }
+            abstractIdentifyRequest_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractIdentifyRequest_);
+              abstractIdentifyRequest_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.RegisterTMRequest.internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.RegisterTMRequest.internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.RegisterTMRequestProto.class, io.seata.codec.protobuf.generated.RegisterTMRequestProto.Builder.class);
+  }
+
+  public static final int ABSTRACTIDENTIFYREQUEST_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto abstractIdentifyRequest_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public boolean hasAbstractIdentifyRequest() {
+    return abstractIdentifyRequest_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest() {
+    return abstractIdentifyRequest_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder() {
+    return getAbstractIdentifyRequest();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractIdentifyRequest_ != null) {
+      output.writeMessage(1, getAbstractIdentifyRequest());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractIdentifyRequest_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractIdentifyRequest());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.RegisterTMRequestProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.RegisterTMRequestProto other = (io.seata.codec.protobuf.generated.RegisterTMRequestProto) obj;
+
+    if (hasAbstractIdentifyRequest() != other.hasAbstractIdentifyRequest()) return false;
+    if (hasAbstractIdentifyRequest()) {
+      if (!getAbstractIdentifyRequest()
+          .equals(other.getAbstractIdentifyRequest())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractIdentifyRequest()) {
+      hash = (37 * hash) + ABSTRACTIDENTIFYREQUEST_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractIdentifyRequest().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.RegisterTMRequestProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.RegisterTMRequestProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.RegisterTMRequestProto)
+      io.seata.codec.protobuf.generated.RegisterTMRequestProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.RegisterTMRequest.internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.RegisterTMRequest.internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.RegisterTMRequestProto.class, io.seata.codec.protobuf.generated.RegisterTMRequestProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.RegisterTMRequestProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = null;
+      } else {
+        abstractIdentifyRequest_ = null;
+        abstractIdentifyRequestBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.RegisterTMRequest.internal_static_io_seata_protocol_protobuf_RegisterTMRequestProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMRequestProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.RegisterTMRequestProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMRequestProto build() {
+      io.seata.codec.protobuf.generated.RegisterTMRequestProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMRequestProto buildPartial() {
+      io.seata.codec.protobuf.generated.RegisterTMRequestProto result = new io.seata.codec.protobuf.generated.RegisterTMRequestProto(this);
+      if (abstractIdentifyRequestBuilder_ == null) {
+        result.abstractIdentifyRequest_ = abstractIdentifyRequest_;
+      } else {
+        result.abstractIdentifyRequest_ = abstractIdentifyRequestBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.RegisterTMRequestProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.RegisterTMRequestProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.RegisterTMRequestProto other) {
+      if (other == io.seata.codec.protobuf.generated.RegisterTMRequestProto.getDefaultInstance()) return this;
+      if (other.hasAbstractIdentifyRequest()) {
+        mergeAbstractIdentifyRequest(other.getAbstractIdentifyRequest());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.RegisterTMRequestProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.RegisterTMRequestProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto abstractIdentifyRequest_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder> abstractIdentifyRequestBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public boolean hasAbstractIdentifyRequest() {
+      return abstractIdentifyRequestBuilder_ != null || abstractIdentifyRequest_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        return abstractIdentifyRequest_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+      } else {
+        return abstractIdentifyRequestBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder setAbstractIdentifyRequest(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto value) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractIdentifyRequest_ = value;
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder setAbstractIdentifyRequest(
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder builderForValue) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder mergeAbstractIdentifyRequest(io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto value) {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        if (abstractIdentifyRequest_ != null) {
+          abstractIdentifyRequest_ =
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.newBuilder(abstractIdentifyRequest_).mergeFrom(value).buildPartial();
+        } else {
+          abstractIdentifyRequest_ = value;
+        }
+        onChanged();
+      } else {
+        abstractIdentifyRequestBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public Builder clearAbstractIdentifyRequest() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequest_ = null;
+        onChanged();
+      } else {
+        abstractIdentifyRequest_ = null;
+        abstractIdentifyRequestBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder getAbstractIdentifyRequestBuilder() {
+      
+      onChanged();
+      return getAbstractIdentifyRequestFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder() {
+      if (abstractIdentifyRequestBuilder_ != null) {
+        return abstractIdentifyRequestBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractIdentifyRequest_ == null ?
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.getDefaultInstance() : abstractIdentifyRequest_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder> 
+        getAbstractIdentifyRequestFieldBuilder() {
+      if (abstractIdentifyRequestBuilder_ == null) {
+        abstractIdentifyRequestBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder>(
+                getAbstractIdentifyRequest(),
+                getParentForChildren(),
+                isClean());
+        abstractIdentifyRequest_ = null;
+      }
+      return abstractIdentifyRequestBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.RegisterTMRequestProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.RegisterTMRequestProto)
+  private static final io.seata.codec.protobuf.generated.RegisterTMRequestProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.RegisterTMRequestProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterTMRequestProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RegisterTMRequestProto>
+      PARSER = new com.google.protobuf.AbstractParser<RegisterTMRequestProto>() {
+    @java.lang.Override
+    public RegisterTMRequestProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RegisterTMRequestProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RegisterTMRequestProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RegisterTMRequestProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.RegisterTMRequestProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..59b1c55c4b7a68365c76109bf860784a487f716d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMRequestProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMRequest.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface RegisterTMRequestProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.RegisterTMRequestProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  boolean hasAbstractIdentifyRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyRequestProto getAbstractIdentifyRequest();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyRequestProto abstractIdentifyRequest = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyRequestProtoOrBuilder getAbstractIdentifyRequestOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponse.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponse.java
new file mode 100644
index 0000000000000000000000000000000000000000..c37a2db46618a3bfe7fa495dbefc2723f0d2b5fd
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponse.java
@@ -0,0 +1,62 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class RegisterTMResponse {
+  private RegisterTMResponse() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\030registerTMResponse.proto\022\032io.seata.pro" +
+      "tocol.protobuf\032\036abstractIdentifyResponse" +
+      ".proto\"v\n\027RegisterTMResponseProto\022[\n\030abs" +
+      "tractIdentifyResponse\030\001 \001(\01329.io.seata.p" +
+      "rotocol.protobuf.AbstractIdentifyRespons" +
+      "eProtoB9\n!io.seata.codec.protobuf.genera" +
+      "tedB\022RegisterTMResponseP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          io.seata.codec.protobuf.generated.AbstractIdentifyResponse.getDescriptor(),
+        }, assigner);
+    internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor,
+        new java.lang.String[] { "AbstractIdentifyResponse", });
+    io.seata.codec.protobuf.generated.AbstractIdentifyResponse.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6f3789e6927b65986b2bf801e0246112436a3d3
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProto.java
@@ -0,0 +1,602 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf type {@code io.seata.protocol.protobuf.RegisterTMResponseProto}
+ */
+public  final class RegisterTMResponseProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:io.seata.protocol.protobuf.RegisterTMResponseProto)
+    RegisterTMResponseProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use RegisterTMResponseProto.newBuilder() to construct.
+  private RegisterTMResponseProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private RegisterTMResponseProto() {
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private RegisterTMResponseProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder subBuilder = null;
+            if (abstractIdentifyResponse_ != null) {
+              subBuilder = abstractIdentifyResponse_.toBuilder();
+            }
+            abstractIdentifyResponse_ = input.readMessage(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(abstractIdentifyResponse_);
+              abstractIdentifyResponse_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.RegisterTMResponse.internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return io.seata.codec.protobuf.generated.RegisterTMResponse.internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            io.seata.codec.protobuf.generated.RegisterTMResponseProto.class, io.seata.codec.protobuf.generated.RegisterTMResponseProto.Builder.class);
+  }
+
+  public static final int ABSTRACTIDENTIFYRESPONSE_FIELD_NUMBER = 1;
+  private io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto abstractIdentifyResponse_;
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public boolean hasAbstractIdentifyResponse() {
+    return abstractIdentifyResponse_ != null;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse() {
+    return abstractIdentifyResponse_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+  }
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder() {
+    return getAbstractIdentifyResponse();
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (abstractIdentifyResponse_ != null) {
+      output.writeMessage(1, getAbstractIdentifyResponse());
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (abstractIdentifyResponse_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getAbstractIdentifyResponse());
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof io.seata.codec.protobuf.generated.RegisterTMResponseProto)) {
+      return super.equals(obj);
+    }
+    io.seata.codec.protobuf.generated.RegisterTMResponseProto other = (io.seata.codec.protobuf.generated.RegisterTMResponseProto) obj;
+
+    if (hasAbstractIdentifyResponse() != other.hasAbstractIdentifyResponse()) return false;
+    if (hasAbstractIdentifyResponse()) {
+      if (!getAbstractIdentifyResponse()
+          .equals(other.getAbstractIdentifyResponse())) return false;
+    }
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasAbstractIdentifyResponse()) {
+      hash = (37 * hash) + ABSTRACTIDENTIFYRESPONSE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbstractIdentifyResponse().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(io.seata.codec.protobuf.generated.RegisterTMResponseProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * PublishRequest is a publish request.
+   * </pre>
+   *
+   * Protobuf type {@code io.seata.protocol.protobuf.RegisterTMResponseProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:io.seata.protocol.protobuf.RegisterTMResponseProto)
+      io.seata.codec.protobuf.generated.RegisterTMResponseProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return io.seata.codec.protobuf.generated.RegisterTMResponse.internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return io.seata.codec.protobuf.generated.RegisterTMResponse.internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              io.seata.codec.protobuf.generated.RegisterTMResponseProto.class, io.seata.codec.protobuf.generated.RegisterTMResponseProto.Builder.class);
+    }
+
+    // Construct using io.seata.codec.protobuf.generated.RegisterTMResponseProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = null;
+      } else {
+        abstractIdentifyResponse_ = null;
+        abstractIdentifyResponseBuilder_ = null;
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return io.seata.codec.protobuf.generated.RegisterTMResponse.internal_static_io_seata_protocol_protobuf_RegisterTMResponseProto_descriptor;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMResponseProto getDefaultInstanceForType() {
+      return io.seata.codec.protobuf.generated.RegisterTMResponseProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMResponseProto build() {
+      io.seata.codec.protobuf.generated.RegisterTMResponseProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public io.seata.codec.protobuf.generated.RegisterTMResponseProto buildPartial() {
+      io.seata.codec.protobuf.generated.RegisterTMResponseProto result = new io.seata.codec.protobuf.generated.RegisterTMResponseProto(this);
+      if (abstractIdentifyResponseBuilder_ == null) {
+        result.abstractIdentifyResponse_ = abstractIdentifyResponse_;
+      } else {
+        result.abstractIdentifyResponse_ = abstractIdentifyResponseBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof io.seata.codec.protobuf.generated.RegisterTMResponseProto) {
+        return mergeFrom((io.seata.codec.protobuf.generated.RegisterTMResponseProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(io.seata.codec.protobuf.generated.RegisterTMResponseProto other) {
+      if (other == io.seata.codec.protobuf.generated.RegisterTMResponseProto.getDefaultInstance()) return this;
+      if (other.hasAbstractIdentifyResponse()) {
+        mergeAbstractIdentifyResponse(other.getAbstractIdentifyResponse());
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      io.seata.codec.protobuf.generated.RegisterTMResponseProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (io.seata.codec.protobuf.generated.RegisterTMResponseProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto abstractIdentifyResponse_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder> abstractIdentifyResponseBuilder_;
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public boolean hasAbstractIdentifyResponse() {
+      return abstractIdentifyResponseBuilder_ != null || abstractIdentifyResponse_ != null;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        return abstractIdentifyResponse_ == null ? io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+      } else {
+        return abstractIdentifyResponseBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder setAbstractIdentifyResponse(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto value) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        abstractIdentifyResponse_ = value;
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder setAbstractIdentifyResponse(
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder builderForValue) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = builderForValue.build();
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder mergeAbstractIdentifyResponse(io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto value) {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        if (abstractIdentifyResponse_ != null) {
+          abstractIdentifyResponse_ =
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.newBuilder(abstractIdentifyResponse_).mergeFrom(value).buildPartial();
+        } else {
+          abstractIdentifyResponse_ = value;
+        }
+        onChanged();
+      } else {
+        abstractIdentifyResponseBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public Builder clearAbstractIdentifyResponse() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponse_ = null;
+        onChanged();
+      } else {
+        abstractIdentifyResponse_ = null;
+        abstractIdentifyResponseBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder getAbstractIdentifyResponseBuilder() {
+      
+      onChanged();
+      return getAbstractIdentifyResponseFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    public io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder() {
+      if (abstractIdentifyResponseBuilder_ != null) {
+        return abstractIdentifyResponseBuilder_.getMessageOrBuilder();
+      } else {
+        return abstractIdentifyResponse_ == null ?
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.getDefaultInstance() : abstractIdentifyResponse_;
+      }
+    }
+    /**
+     * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder> 
+        getAbstractIdentifyResponseFieldBuilder() {
+      if (abstractIdentifyResponseBuilder_ == null) {
+        abstractIdentifyResponseBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto.Builder, io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder>(
+                getAbstractIdentifyResponse(),
+                getParentForChildren(),
+                isClean());
+        abstractIdentifyResponse_ = null;
+      }
+      return abstractIdentifyResponseBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:io.seata.protocol.protobuf.RegisterTMResponseProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:io.seata.protocol.protobuf.RegisterTMResponseProto)
+  private static final io.seata.codec.protobuf.generated.RegisterTMResponseProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new io.seata.codec.protobuf.generated.RegisterTMResponseProto();
+  }
+
+  public static io.seata.codec.protobuf.generated.RegisterTMResponseProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<RegisterTMResponseProto>
+      PARSER = new com.google.protobuf.AbstractParser<RegisterTMResponseProto>() {
+    @java.lang.Override
+    public RegisterTMResponseProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new RegisterTMResponseProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<RegisterTMResponseProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<RegisterTMResponseProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public io.seata.codec.protobuf.generated.RegisterTMResponseProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProtoOrBuilder.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProtoOrBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..87b08c955d23cde089d2e4f60b9890fd190d04b9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/RegisterTMResponseProtoOrBuilder.java
@@ -0,0 +1,22 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: registerTMResponse.proto
+
+package io.seata.codec.protobuf.generated;
+
+public interface RegisterTMResponseProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:io.seata.protocol.protobuf.RegisterTMResponseProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  boolean hasAbstractIdentifyResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyResponseProto getAbstractIdentifyResponse();
+  /**
+   * <code>.io.seata.protocol.protobuf.AbstractIdentifyResponseProto abstractIdentifyResponse = 1;</code>
+   */
+  io.seata.codec.protobuf.generated.AbstractIdentifyResponseProtoOrBuilder getAbstractIdentifyResponseOrBuilder();
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCode.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCode.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5e4398ff118ea32b4bbf27903613a93fa6190be
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCode.java
@@ -0,0 +1,46 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: resultCode.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class ResultCode {
+  private ResultCode() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020resultCode.proto\022\032io.seata.protocol.pr" +
+      "otobuf**\n\017ResultCodeProto\022\n\n\006Failed\020\000\022\013\n" +
+      "\007Success\020\001B1\n!io.seata.codec.protobuf.ge" +
+      "neratedB\nResultCodeP\001b\006proto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCodeProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCodeProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..55c7d7148c2ca614357476cda1db0797a0d99edf
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/ResultCodeProto.java
@@ -0,0 +1,107 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: resultCode.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.ResultCodeProto}
+ */
+public enum ResultCodeProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <code>Failed = 0;</code>
+   */
+  Failed(0),
+  /**
+   * <code>Success = 1;</code>
+   */
+  Success(1),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <code>Failed = 0;</code>
+   */
+  public static final int Failed_VALUE = 0;
+  /**
+   * <code>Success = 1;</code>
+   */
+  public static final int Success_VALUE = 1;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static ResultCodeProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static ResultCodeProto forNumber(int value) {
+    switch (value) {
+      case 0: return Failed;
+      case 1: return Success;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<ResultCodeProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      ResultCodeProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<ResultCodeProto>() {
+          public ResultCodeProto findValueByNumber(int number) {
+            return ResultCodeProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.ResultCode.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final ResultCodeProto[] VALUES = values();
+
+  public static ResultCodeProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private ResultCodeProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.ResultCodeProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCode.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCode.java
new file mode 100644
index 0000000000000000000000000000000000000000..b005ec938082472955ffeb9fc08ee7b15c9b35be
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCode.java
@@ -0,0 +1,59 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: transactionExceptionCode.proto
+
+package io.seata.codec.protobuf.generated;
+
+public final class TransactionExceptionCode {
+  private TransactionExceptionCode() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\036transactionExceptionCode.proto\022\032io.sea" +
+      "ta.protocol.protobuf*\374\003\n\035TransactionExce" +
+      "ptionCodeProto\022\013\n\007Unknown\020\000\022\023\n\017LockKeyCo" +
+      "nflict\020\001\022\006\n\002IO\020\002\022\"\n\036BranchRollbackFailed" +
+      "_Retriable\020\003\022$\n BranchRollbackFailed_Unr" +
+      "etriable\020\004\022\030\n\024BranchRegisterFailed\020\005\022\026\n\022" +
+      "BranchReportFailed\020\006\022\027\n\023LockableCheckFai" +
+      "led\020\007\022\035\n\031BranchTransactionNotExist\020\010\022\035\n\031" +
+      "GlobalTransactionNotExist\020\t\022\036\n\032GlobalTra" +
+      "nsactionNotActive\020\n\022\"\n\036GlobalTransaction" +
+      "StatusInvalid\020\013\022#\n\037FailedToSendBranchCom" +
+      "mitRequest\020\014\022%\n!FailedToSendBranchRollba" +
+      "ckRequest\020\r\022\025\n\021FailedToAddBranch\020\016\022\037\n\033Fa" +
+      "iledLockGlobalTranscation\020\017\022\026\n\022FailedWri" +
+      "teSession\020\020B?\n!io.seata.codec.protobuf.g" +
+      "eneratedB\030TransactionExceptionCodeP\001b\006pr" +
+      "oto3"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
+          public com.google.protobuf.ExtensionRegistry assignDescriptors(
+              com.google.protobuf.Descriptors.FileDescriptor root) {
+            descriptor = root;
+            return null;
+          }
+        };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCodeProto.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCodeProto.java
new file mode 100644
index 0000000000000000000000000000000000000000..18626fa634aa17e678a11b9cd8a4ff43dd9650d9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated/TransactionExceptionCodeProto.java
@@ -0,0 +1,352 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: transactionExceptionCode.proto
+
+package io.seata.codec.protobuf.generated;
+
+/**
+ * <pre>
+ * PublishRequest is a publish request.
+ * </pre>
+ *
+ * Protobuf enum {@code io.seata.protocol.protobuf.TransactionExceptionCodeProto}
+ */
+public enum TransactionExceptionCodeProto
+    implements com.google.protobuf.ProtocolMessageEnum {
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>Unknown = 0;</code>
+   */
+  Unknown(0),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>LockKeyConflict = 1;</code>
+   */
+  LockKeyConflict(1),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>IO = 2;</code>
+   */
+  IO(2),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRollbackFailed_Retriable = 3;</code>
+   */
+  BranchRollbackFailed_Retriable(3),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRollbackFailed_Unretriable = 4;</code>
+   */
+  BranchRollbackFailed_Unretriable(4),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRegisterFailed = 5;</code>
+   */
+  BranchRegisterFailed(5),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchReportFailed = 6;</code>
+   */
+  BranchReportFailed(6),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>LockableCheckFailed = 7;</code>
+   */
+  LockableCheckFailed(7),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchTransactionNotExist = 8;</code>
+   */
+  BranchTransactionNotExist(8),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionNotExist = 9;</code>
+   */
+  GlobalTransactionNotExist(9),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionNotActive = 10;</code>
+   */
+  GlobalTransactionNotActive(10),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionStatusInvalid = 11;</code>
+   */
+  GlobalTransactionStatusInvalid(11),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToSendBranchCommitRequest = 12;</code>
+   */
+  FailedToSendBranchCommitRequest(12),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToSendBranchRollbackRequest = 13;</code>
+   */
+  FailedToSendBranchRollbackRequest(13),
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToAddBranch = 14;</code>
+   */
+  FailedToAddBranch(14),
+  /**
+   * <pre>
+   **
+   *  Failed to lock global transaction exception code.
+   * </pre>
+   *
+   * <code>FailedLockGlobalTranscation = 15;</code>
+   */
+  FailedLockGlobalTranscation(15),
+  /**
+   * <pre>
+   **
+   * FailedWriteSession
+   * </pre>
+   *
+   * <code>FailedWriteSession = 16;</code>
+   */
+  FailedWriteSession(16),
+  UNRECOGNIZED(-1),
+  ;
+
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>Unknown = 0;</code>
+   */
+  public static final int Unknown_VALUE = 0;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>LockKeyConflict = 1;</code>
+   */
+  public static final int LockKeyConflict_VALUE = 1;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>IO = 2;</code>
+   */
+  public static final int IO_VALUE = 2;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRollbackFailed_Retriable = 3;</code>
+   */
+  public static final int BranchRollbackFailed_Retriable_VALUE = 3;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRollbackFailed_Unretriable = 4;</code>
+   */
+  public static final int BranchRollbackFailed_Unretriable_VALUE = 4;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchRegisterFailed = 5;</code>
+   */
+  public static final int BranchRegisterFailed_VALUE = 5;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchReportFailed = 6;</code>
+   */
+  public static final int BranchReportFailed_VALUE = 6;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>LockableCheckFailed = 7;</code>
+   */
+  public static final int LockableCheckFailed_VALUE = 7;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>BranchTransactionNotExist = 8;</code>
+   */
+  public static final int BranchTransactionNotExist_VALUE = 8;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionNotExist = 9;</code>
+   */
+  public static final int GlobalTransactionNotExist_VALUE = 9;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionNotActive = 10;</code>
+   */
+  public static final int GlobalTransactionNotActive_VALUE = 10;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>GlobalTransactionStatusInvalid = 11;</code>
+   */
+  public static final int GlobalTransactionStatusInvalid_VALUE = 11;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToSendBranchCommitRequest = 12;</code>
+   */
+  public static final int FailedToSendBranchCommitRequest_VALUE = 12;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToSendBranchRollbackRequest = 13;</code>
+   */
+  public static final int FailedToSendBranchRollbackRequest_VALUE = 13;
+  /**
+   * <pre>
+   * </pre>
+   *
+   * <code>FailedToAddBranch = 14;</code>
+   */
+  public static final int FailedToAddBranch_VALUE = 14;
+  /**
+   * <pre>
+   **
+   *  Failed to lock global transaction exception code.
+   * </pre>
+   *
+   * <code>FailedLockGlobalTranscation = 15;</code>
+   */
+  public static final int FailedLockGlobalTranscation_VALUE = 15;
+  /**
+   * <pre>
+   **
+   * FailedWriteSession
+   * </pre>
+   *
+   * <code>FailedWriteSession = 16;</code>
+   */
+  public static final int FailedWriteSession_VALUE = 16;
+
+
+  public final int getNumber() {
+    if (this == UNRECOGNIZED) {
+      throw new java.lang.IllegalArgumentException(
+          "Can't get the number of an unknown enum value.");
+    }
+    return value;
+  }
+
+  /**
+   * @deprecated Use {@link #forNumber(int)} instead.
+   */
+  @java.lang.Deprecated
+  public static TransactionExceptionCodeProto valueOf(int value) {
+    return forNumber(value);
+  }
+
+  public static TransactionExceptionCodeProto forNumber(int value) {
+    switch (value) {
+      case 0: return Unknown;
+      case 1: return LockKeyConflict;
+      case 2: return IO;
+      case 3: return BranchRollbackFailed_Retriable;
+      case 4: return BranchRollbackFailed_Unretriable;
+      case 5: return BranchRegisterFailed;
+      case 6: return BranchReportFailed;
+      case 7: return LockableCheckFailed;
+      case 8: return BranchTransactionNotExist;
+      case 9: return GlobalTransactionNotExist;
+      case 10: return GlobalTransactionNotActive;
+      case 11: return GlobalTransactionStatusInvalid;
+      case 12: return FailedToSendBranchCommitRequest;
+      case 13: return FailedToSendBranchRollbackRequest;
+      case 14: return FailedToAddBranch;
+      case 15: return FailedLockGlobalTranscation;
+      case 16: return FailedWriteSession;
+      default: return null;
+    }
+  }
+
+  public static com.google.protobuf.Internal.EnumLiteMap<TransactionExceptionCodeProto>
+      internalGetValueMap() {
+    return internalValueMap;
+  }
+  private static final com.google.protobuf.Internal.EnumLiteMap<
+      TransactionExceptionCodeProto> internalValueMap =
+        new com.google.protobuf.Internal.EnumLiteMap<TransactionExceptionCodeProto>() {
+          public TransactionExceptionCodeProto findValueByNumber(int number) {
+            return TransactionExceptionCodeProto.forNumber(number);
+          }
+        };
+
+  public final com.google.protobuf.Descriptors.EnumValueDescriptor
+      getValueDescriptor() {
+    return getDescriptor().getValues().get(ordinal());
+  }
+  public final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptorForType() {
+    return getDescriptor();
+  }
+  public static final com.google.protobuf.Descriptors.EnumDescriptor
+      getDescriptor() {
+    return io.seata.codec.protobuf.generated.TransactionExceptionCode.getDescriptor().getEnumTypes().get(0);
+  }
+
+  private static final TransactionExceptionCodeProto[] VALUES = values();
+
+  public static TransactionExceptionCodeProto valueOf(
+      com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+    if (desc.getType() != getDescriptor()) {
+      throw new java.lang.IllegalArgumentException(
+        "EnumValueDescriptor is not for this type.");
+    }
+    if (desc.getIndex() == -1) {
+      return UNRECOGNIZED;
+    }
+    return VALUES[desc.getIndex()];
+  }
+
+  private final int value;
+
+  private TransactionExceptionCodeProto(int value) {
+    this.value = value;
+  }
+
+  // @@protoc_insertion_point(enum_scope:io.seata.protocol.protobuf.TransactionExceptionCodeProto)
+}
+
diff --git a/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/manager/ProtobufConvertManager.java b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/manager/ProtobufConvertManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..8af7c81ef0424b6c48d4362b928cec81848a3ba9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/manager/ProtobufConvertManager.java
@@ -0,0 +1,295 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.manager;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import io.seata.codec.protobuf.convertor.BranchCommitRequestConvertor;
+import io.seata.codec.protobuf.convertor.BranchCommitResponseConvertor;
+import io.seata.codec.protobuf.convertor.BranchRegisterRequestConvertor;
+import io.seata.codec.protobuf.convertor.BranchRegisterResponseConvertor;
+import io.seata.codec.protobuf.convertor.BranchReportRequestConvertor;
+import io.seata.codec.protobuf.convertor.BranchReportResponseConvertor;
+import io.seata.codec.protobuf.convertor.BranchRollbackRequestConvertor;
+import io.seata.codec.protobuf.convertor.BranchRollbackResponseConvertor;
+import io.seata.codec.protobuf.convertor.GlobalBeginRequestConvertor;
+import io.seata.codec.protobuf.convertor.GlobalBeginResponseConvertor;
+import io.seata.codec.protobuf.convertor.GlobalCommitRequestConvertor;
+import io.seata.codec.protobuf.convertor.GlobalCommitResponseConvertor;
+import io.seata.codec.protobuf.convertor.GlobalLockQueryRequestConvertor;
+import io.seata.codec.protobuf.convertor.GlobalLockQueryResponseConvertor;
+import io.seata.codec.protobuf.convertor.GlobalRollbackRequestConvertor;
+import io.seata.codec.protobuf.convertor.GlobalRollbackResponseConvertor;
+import io.seata.codec.protobuf.convertor.GlobalStatusRequestConvertor;
+import io.seata.codec.protobuf.convertor.GlobalStatusResponseConvertor;
+import io.seata.codec.protobuf.convertor.HeartbeatMessageConvertor;
+import io.seata.codec.protobuf.convertor.MergeResultMessageConvertor;
+import io.seata.codec.protobuf.convertor.MergedWarpMessageConvertor;
+import io.seata.codec.protobuf.convertor.PbConvertor;
+import io.seata.codec.protobuf.convertor.RegisterRMRequestConvertor;
+import io.seata.codec.protobuf.convertor.RegisterRMResponseConvertor;
+import io.seata.codec.protobuf.convertor.RegisterTMRequestConvertor;
+import io.seata.codec.protobuf.convertor.RegisterTMResponseConvertor;
+import io.seata.core.protocol.HeartbeatMessage;
+import io.seata.core.protocol.MergeResultMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+import io.seata.core.protocol.RegisterRMRequest;
+import io.seata.core.protocol.RegisterRMResponse;
+import io.seata.core.protocol.RegisterTMRequest;
+import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.codec.protobuf.generated.BranchCommitRequestProto;
+import io.seata.codec.protobuf.generated.BranchCommitResponseProto;
+import io.seata.codec.protobuf.generated.BranchRegisterRequestProto;
+import io.seata.codec.protobuf.generated.BranchRegisterResponseProto;
+import io.seata.codec.protobuf.generated.BranchReportRequestProto;
+import io.seata.codec.protobuf.generated.BranchReportResponseProto;
+import io.seata.codec.protobuf.generated.BranchRollbackRequestProto;
+import io.seata.codec.protobuf.generated.BranchRollbackResponseProto;
+import io.seata.codec.protobuf.generated.GlobalBeginRequestProto;
+import io.seata.codec.protobuf.generated.GlobalBeginResponseProto;
+import io.seata.codec.protobuf.generated.GlobalCommitRequestProto;
+import io.seata.codec.protobuf.generated.GlobalCommitResponseProto;
+import io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto;
+import io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto;
+import io.seata.codec.protobuf.generated.GlobalRollbackRequestProto;
+import io.seata.codec.protobuf.generated.GlobalRollbackResponseProto;
+import io.seata.codec.protobuf.generated.GlobalStatusRequestProto;
+import io.seata.codec.protobuf.generated.GlobalStatusResponseProto;
+import io.seata.codec.protobuf.generated.HeartbeatMessageProto;
+import io.seata.codec.protobuf.generated.MergedResultMessageProto;
+import io.seata.codec.protobuf.generated.MergedWarpMessageProto;
+import io.seata.codec.protobuf.generated.RegisterRMRequestProto;
+import io.seata.codec.protobuf.generated.RegisterRMResponseProto;
+import io.seata.codec.protobuf.generated.RegisterTMRequestProto;
+import io.seata.codec.protobuf.generated.RegisterTMResponseProto;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+import io.seata.core.protocol.transaction.BranchReportResponse;
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+
+/**
+ * @author leizhiyuan
+ */
+public class ProtobufConvertManager {
+
+    private Map<String, PbConvertor> convertorMap = new ConcurrentHashMap<>();
+
+    private Map<String, PbConvertor> reverseConvertorMap = new ConcurrentHashMap<>();
+
+    private Map<String, Class> protoClazzMap = new ConcurrentHashMap<>();
+
+    private static class SingletonHolder {
+        private static final ProtobufConvertManager INSTANCE;
+
+        static {
+            final ProtobufConvertManager protobufConvertManager = new ProtobufConvertManager();
+            protobufConvertManager.convertorMap.put(GlobalBeginRequest.class.getName(),
+                new GlobalBeginRequestConvertor());
+            protobufConvertManager.convertorMap.put(BranchCommitRequest.class.getName(),
+                new BranchCommitRequestConvertor());
+            protobufConvertManager.convertorMap.put(BranchCommitResponse.class.getName(),
+                new BranchCommitResponseConvertor());
+            protobufConvertManager.convertorMap.put(BranchRegisterRequest.class.getName(),
+                new BranchRegisterRequestConvertor());
+            protobufConvertManager.convertorMap.put(BranchRegisterResponse.class.getName(),
+                new BranchRegisterResponseConvertor());
+            protobufConvertManager.convertorMap.put(BranchReportRequest.class.getName(),
+                new BranchReportRequestConvertor());
+            protobufConvertManager.convertorMap.put(BranchReportResponse.class.getName(),
+                new BranchReportResponseConvertor());
+            protobufConvertManager.convertorMap.put(BranchRollbackRequest.class.getName(),
+                new BranchRollbackRequestConvertor());
+            protobufConvertManager.convertorMap.put(BranchRollbackResponse.class.getName(),
+                new BranchRollbackResponseConvertor());
+            protobufConvertManager.convertorMap.put(GlobalBeginResponse.class.getName(),
+                new GlobalBeginResponseConvertor());
+            protobufConvertManager.convertorMap.put(GlobalCommitRequest.class.getName(),
+                new GlobalCommitRequestConvertor());
+            protobufConvertManager.convertorMap.put(GlobalCommitResponse.class.getName(),
+                new GlobalCommitResponseConvertor());
+            protobufConvertManager.convertorMap.put(GlobalLockQueryRequest.class.getName(),
+                new GlobalLockQueryRequestConvertor());
+            protobufConvertManager.convertorMap.put(GlobalLockQueryResponse.class.getName(),
+                new GlobalLockQueryResponseConvertor());
+            protobufConvertManager.convertorMap.put(GlobalRollbackRequest.class.getName(),
+                new GlobalRollbackRequestConvertor());
+            protobufConvertManager.convertorMap.put(GlobalRollbackResponse.class.getName(),
+                new GlobalRollbackResponseConvertor());
+            protobufConvertManager.convertorMap.put(GlobalStatusRequest.class.getName(),
+                new GlobalStatusRequestConvertor());
+            protobufConvertManager.convertorMap.put(GlobalStatusResponse.class.getName(),
+                new GlobalStatusResponseConvertor());
+
+            protobufConvertManager.convertorMap.put(MergedWarpMessage.class.getName(),
+                new MergedWarpMessageConvertor());
+            protobufConvertManager.convertorMap.put(HeartbeatMessage.class.getName(), new HeartbeatMessageConvertor());
+            protobufConvertManager.convertorMap.put(MergeResultMessage.class.getName(),
+                new MergeResultMessageConvertor());
+            protobufConvertManager.convertorMap.put(RegisterRMRequest.class.getName(),
+                new RegisterRMRequestConvertor());
+            protobufConvertManager.convertorMap.put(RegisterRMResponse.class.getName(),
+                new RegisterRMResponseConvertor());
+            protobufConvertManager.convertorMap.put(RegisterTMRequest.class.getName(),
+                new RegisterTMRequestConvertor());
+            protobufConvertManager.convertorMap.put(RegisterTMResponse.class.getName(),
+                new RegisterTMResponseConvertor());
+
+            protobufConvertManager.protoClazzMap.put(GlobalBeginRequestProto.getDescriptor().getFullName(),
+                GlobalBeginRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchCommitRequestProto.getDescriptor().getFullName(),
+                BranchCommitRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchCommitResponseProto.getDescriptor().getFullName(),
+                BranchCommitResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchRegisterRequestProto.getDescriptor().getFullName(),
+                BranchRegisterRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchRegisterResponseProto.getDescriptor().getFullName(),
+                BranchRegisterResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchReportRequestProto.getDescriptor().getFullName(),
+                BranchReportRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchReportResponseProto.getDescriptor().getFullName(),
+                BranchReportResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchRollbackRequestProto.getDescriptor().getFullName(),
+                BranchRollbackRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(BranchRollbackResponseProto.getDescriptor().getFullName(),
+                BranchRollbackResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalBeginResponseProto.getDescriptor().getFullName(),
+                GlobalBeginResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalCommitRequestProto.getDescriptor().getFullName(),
+                GlobalCommitRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalCommitResponseProto.getDescriptor().getFullName(),
+                GlobalCommitResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalLockQueryRequestProto.getDescriptor().getFullName(),
+                GlobalLockQueryRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalLockQueryResponseProto.getDescriptor().getFullName(),
+                GlobalLockQueryResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalRollbackRequestProto.getDescriptor().getFullName(),
+                GlobalRollbackRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalRollbackResponseProto.getDescriptor().getFullName(),
+                GlobalRollbackResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalStatusRequestProto.getDescriptor().getFullName(),
+                GlobalStatusRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(GlobalStatusResponseProto.getDescriptor().getFullName(),
+                GlobalStatusResponseProto.class);
+
+            protobufConvertManager.protoClazzMap.put(MergedWarpMessageProto.getDescriptor().getFullName(),
+                MergedWarpMessageProto.class);
+            protobufConvertManager.protoClazzMap.put(HeartbeatMessageProto.getDescriptor().getFullName(),
+                HeartbeatMessageProto.class);
+            protobufConvertManager.protoClazzMap.put(MergedResultMessageProto.getDescriptor().getFullName(),
+                MergedResultMessageProto.class);
+            protobufConvertManager.protoClazzMap.put(RegisterRMRequestProto.getDescriptor().getFullName(),
+                RegisterRMRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(RegisterRMResponseProto.getDescriptor().getFullName(),
+                RegisterRMResponseProto.class);
+            protobufConvertManager.protoClazzMap.put(RegisterTMRequestProto.getDescriptor().getFullName(),
+                RegisterTMRequestProto.class);
+            protobufConvertManager.protoClazzMap.put(RegisterTMResponseProto.getDescriptor().getFullName(),
+                RegisterTMResponseProto.class);
+
+            protobufConvertManager.reverseConvertorMap.put(GlobalBeginRequestProto.class.getName(),
+                new GlobalBeginRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchCommitRequestProto.class.getName(),
+                new BranchCommitRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchCommitResponseProto.class.getName(),
+                new BranchCommitResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchRegisterRequestProto.class.getName(),
+                new BranchRegisterRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchRegisterResponseProto.class.getName(),
+                new BranchRegisterResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchReportRequestProto.class.getName(),
+                new BranchReportRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchReportResponseProto.class.getName(),
+                new BranchReportResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchRollbackRequestProto.class.getName(),
+                new BranchRollbackRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(BranchRollbackResponseProto.class.getName(),
+                new BranchRollbackResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalBeginResponseProto.class.getName(),
+                new GlobalBeginResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalCommitRequestProto.class.getName(),
+                new GlobalCommitRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalCommitResponseProto.class.getName(),
+                new GlobalCommitResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalLockQueryRequestProto.class.getName(),
+                new GlobalLockQueryRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalLockQueryResponseProto.class.getName(),
+                new GlobalLockQueryResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalRollbackRequestProto.class.getName(),
+                new GlobalRollbackRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalRollbackResponseProto.class.getName(),
+                new GlobalRollbackResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalStatusRequestProto.class.getName(),
+                new GlobalStatusRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(GlobalStatusResponseProto.class.getName(),
+                new GlobalStatusResponseConvertor());
+
+            protobufConvertManager.reverseConvertorMap.put(MergedWarpMessageProto.class.getName(),
+                new MergedWarpMessageConvertor());
+            protobufConvertManager.reverseConvertorMap.put(HeartbeatMessageProto.class.getName(),
+                new HeartbeatMessageConvertor());
+            protobufConvertManager.reverseConvertorMap.put(MergedResultMessageProto.class.getName(),
+                new MergeResultMessageConvertor());
+            protobufConvertManager.reverseConvertorMap.put(RegisterRMRequestProto.class.getName(),
+                new RegisterRMRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(RegisterRMResponseProto.class.getName(),
+                new RegisterRMResponseConvertor());
+            protobufConvertManager.reverseConvertorMap.put(RegisterTMRequestProto.class.getName(),
+                new RegisterTMRequestConvertor());
+            protobufConvertManager.reverseConvertorMap.put(RegisterTMResponseProto.class.getName(),
+                new RegisterTMResponseConvertor());
+
+            INSTANCE = protobufConvertManager;
+        }
+
+    }
+
+    /**
+     * Gets instance.
+     *
+     * @return the instance
+     */
+    public static final ProtobufConvertManager getInstance() {
+        return SingletonHolder.INSTANCE;
+    }
+
+    public PbConvertor fetchConvertor(String clazz) {
+        return convertorMap.get(clazz);
+    }
+
+    public PbConvertor fetchReversedConvertor(String clazz) {
+        return reverseConvertorMap.get(clazz);
+    }
+
+    public Class fetchProtoClass(String clazz) {
+        return protoClazzMap.get(clazz);
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/META-INF/services/io.seata.core.codec.Codec b/codec/seata-codec-protobuf/src/main/resources/META-INF/services/io.seata.core.codec.Codec
new file mode 100644
index 0000000000000000000000000000000000000000..64498071e913fb62ed2e83603ee049ec95f78eac
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/META-INF/services/io.seata.core.codec.Codec
@@ -0,0 +1 @@
+io.seata.codec.protobuf.ProtobufCodec
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..ef5deae341aa76215e53c555de14eb2366dd05f2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndRequest.proto
@@ -0,0 +1,35 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionRequest.proto";
+import "branchType.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractBranchEndRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractBranchEndRequestProto {
+    AbstractTransactionRequestProto abstractTransactionRequest = 1;
+    string xid = 2;
+    /**
+    * The Branch id.
+    */
+    int64 branchId = 3;
+
+    /**
+     * The Branch type.
+     */
+    BranchTypeProto branchType = 4;
+
+    /**
+     * The Resource id.
+     */
+    string resourceId = 5;
+
+    /**
+     * The Application data.
+     */
+    string applicationData = 6;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..31d9712fd1216ae5df0e2e639d05176e599dece8
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractBranchEndResponse.proto
@@ -0,0 +1,19 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+import "branchStatus.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractBranchEndResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractBranchEndResponseProto {
+
+    AbstractTransactionResponseProto abstractTransactionResponse =1;
+    string xid = 2;
+    int64 branchId = 3;
+    BranchStatusProto branchStatus = 4;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..a4b7739ca136c9382ecab0040f3f5996f859753f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndRequest.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractGlobalEndRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractGlobalEndRequestProto {
+
+    AbstractTransactionRequestProto abstractTransactionRequest =1;
+    string xid = 2;
+    string extraData = 3;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3eefeae67aa7c0262ef75698755621816617fd2d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractGlobalEndResponse.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+import "globalStatus.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractGlobalEndResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractGlobalEndResponseProto {
+    AbstractTransactionResponseProto abstractTransactionResponse = 1;
+    GlobalStatusProto globalStatus = 2;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..7e1b54e192ea7c8f0863dc24872c4026c3ab574c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyRequest.proto
@@ -0,0 +1,24 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractMessage.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractIdentifyRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractIdentifyRequestProto {
+
+    AbstractMessageProto abstractMessage=1;
+
+    string version = 2;
+
+    string applicationId = 3;
+
+    string transactionServiceGroup = 4;
+
+    string extraData = 5;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e767c26576d8dbdbc9303e8ef7bc3538d99516e1
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractIdentifyResponse.proto
@@ -0,0 +1,19 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractResultMessage.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractIdentifyResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractIdentifyResponseProto {
+
+    AbstractResultMessageProto abstractResultMessage=1;
+    string version = 2;
+    string extraData = 3;
+    bool identified = 4;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractMessage.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractMessage.proto
new file mode 100644
index 0000000000000000000000000000000000000000..b5a8398bb65f791f4c8751979e1a1e84aef27019
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractMessage.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "messageType.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractMessage";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractMessageProto {
+    MessageTypeProto messageType = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractResultMessage.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractResultMessage.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3a99eff217a1e36377115ecf705f1d712d65232d
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractResultMessage.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "resultCode.proto";
+import "abstractMessage.proto";
+option java_multiple_files = true;
+option java_outer_classname = "AbstractResultMessage";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractResultMessageProto {
+    AbstractMessageProto AbstractMessage=1;
+    ResultCodeProto resultCode = 2;
+    string msg = 3;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..63cdf0300ca51ff8936ded655bcca1a2ddfa71c3
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionRequest.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractMessage.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractTransactionRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractTransactionRequestProto {
+    AbstractMessageProto abstractMessage=1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..08eea060f207555114322532b224a8d495a4119f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/abstractTransactionResponse.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractResultMessage.proto";
+import "transactionExceptionCode.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "AbstractTransactionResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message AbstractTransactionResponseProto {
+    AbstractResultMessageProto abstractResultMessage = 1;
+    TransactionExceptionCodeProto transactionExceptionCode = 2;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..cc98888c8958c19c959b43407e8e4b0026c88337
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitRequest.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractBranchEndRequest.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchCommitRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchCommitRequestProto {
+    AbstractBranchEndRequestProto abstractBranchEndRequest = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..2bc16f1c66073159018efee20f413d084c0d4097
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchCommitResponse.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractBranchEndResponse.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchCommitResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchCommitResponseProto {
+    AbstractBranchEndResponseProto abstractBranchEndResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..114c60c18fb1eb2816098b46f5c2374ce5570e65
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterRequest.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "branchType.proto";
+import "abstractTransactionRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchRegisterRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchRegisterRequestProto {
+    AbstractTransactionRequestProto abstractTransactionRequest =1;
+    string xid = 2;
+    BranchTypeProto branchType = 3;
+    string resourceId = 4;
+    string lockKey = 5;
+    string applicationData = 6;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..bbe8c1f4322d364190ce91b94b6b1ea6f2f7f220
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRegisterResponse.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchRegisterResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchRegisterResponseProto {
+    AbstractTransactionResponseProto abstractTransactionResponse = 1;
+    int64 branchId = 2;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..258519ef8786201fa972635f272e77c75632414b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportRequest.proto
@@ -0,0 +1,28 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "branchStatus.proto";
+import "branchType.proto";
+import "abstractTransactionRequest.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchReportRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message BranchReportRequestProto {
+
+    AbstractTransactionRequestProto abstractTransactionRequest =1;
+    string xid = 2;
+
+    int64 branchId = 3;
+
+    string resourceId = 4;
+
+    BranchStatusProto status = 5;
+
+    string applicationData = 6;
+
+    BranchTypeProto branchType = 7;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..11e9b866a04d8a08550a19eb5a53f01b37c3e273
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchReportResponse.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchReportResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message BranchReportResponseProto {
+    AbstractTransactionResponseProto abstractTransactionResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..c2b9df98a4b06ab7e9dbc8075165e930ed0280bc
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackRequest.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractBranchEndRequest.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchRollbackRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchRollbackRequestProto {
+    AbstractBranchEndRequestProto abstractBranchEndRequest = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..50ae2841c9bfa8a8298b5309cabd33c36e1b51a5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchRollbackResponse.proto
@@ -0,0 +1,15 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractBranchEndResponse.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchRollbackResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message BranchRollbackResponseProto {
+    AbstractBranchEndResponseProto abstractBranchEndResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchStatus.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchStatus.proto
new file mode 100644
index 0000000000000000000000000000000000000000..61cf7bd7d0fbb5b136001828dc260d179d807447
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchStatus.proto
@@ -0,0 +1,78 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchStatus";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum BranchStatusProto {
+
+    /**
+     * Unknown branch status.
+     */
+    // special for Unknown
+    BUnknown = 0;
+
+    /**
+     * The Registered.
+     */
+    // Registered to TC.
+    Registered = 1;
+
+    /**
+     * The Phase one done.
+     */
+    // Branch logic is successfully done at phase one.
+    PhaseOne_Done = 2;
+
+    /**
+     * The Phase one failed.
+     */
+    // Branch logic is failed at phase one.
+    PhaseOne_Failed = 3;
+
+    /**
+     * The Phase one timeout.
+     */
+    // Branch logic is NOT reported for a timeout.
+    PhaseOne_Timeout = 4;
+
+    /**
+     * The Phase two committed.
+     */
+    // Commit logic is successfully done at phase two.
+    PhaseTwo_Committed = 5;
+
+    /**
+     * The Phase two commit failed retryable.
+     */
+    // Commit logic is failed but retryable.
+    PhaseTwo_CommitFailed_Retryable = 6;
+
+    /**
+     * The Phase two commit failed unretryable.
+     */
+    // Commit logic is failed and NOT retryable.
+    PhaseTwo_CommitFailed_Unretryable = 7;
+
+    /**
+     * The Phase two rollbacked.
+     */
+    // Rollback logic is successfully done at phase two.
+    PhaseTwo_Rollbacked = 8;
+
+    /**
+     * The Phase two rollback failed retryable.
+     */
+    // Rollback logic is failed but retryable.
+    PhaseTwo_RollbackFailed_Retryable = 9;
+
+    /**
+     * The Phase two rollback failed unretryable.
+     */
+    // Rollback logic is failed but NOT retryable.
+    PhaseTwo_RollbackFailed_Unretryable = 10;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchType.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchType.proto
new file mode 100644
index 0000000000000000000000000000000000000000..190232e2e8b4e9256ba1292fe45522a7b7f177c9
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/branchType.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "BranchType";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum BranchTypeProto {
+
+    AT = 0;
+
+    TCC = 1;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..61879b38dac7996a8e6d4da90528480149562f04
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginRequest.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionRequest.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalBeginRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalBeginRequestProto {
+    AbstractTransactionRequestProto abstractTransactionRequest=1;
+    int32 timeout = 2;
+    string transactionName = 3;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..bc99b23075977e6bde27acf7a02be434d1fa0df1
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalBeginResponse.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalBeginResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalBeginResponseProto {
+    AbstractTransactionResponseProto abstractTransactionResponse =1;
+    string xid = 2;
+    string extraData = 3;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e3c7ece4e2c8036138198fcb6b3bf2d1795ad4ca
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitRequest.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalCommitRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalCommitRequestProto {
+    AbstractGlobalEndRequestProto abstractGlobalEndRequest =1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..bc0bf1a856983f0507698f55ae9ebdb5d3f99550
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalCommitResponse.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalCommitResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalCommitResponseProto {
+    AbstractGlobalEndResponseProto abstractGlobalEndResponse =1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..4813ff41c56de47fc18eb64b7fcef22dd59832cc
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryRequest.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "branchRegisterRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalLockQueryRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalLockQueryRequestProto {
+    BranchRegisterRequestProto branchRegisterRequest =1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..7766a921791e91d42ee70fe27219c1b8c94ecb84
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalLockQueryResponse.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractTransactionResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalLockQueryResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalLockQueryResponseProto {
+    AbstractTransactionResponseProto abstractTransactionResponse = 1;
+    bool lockable = 2;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..4df0e4467e4f9f2e5787757df1d9e1587acc713f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackRequest.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalRollbackRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalRollbackRequestProto {
+    AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..9daddbb3b2685fa59c57e18c5e1bb1ebd2b6e8ca
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalRollbackResponse.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalRollbackResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalRollbackResponseProto {
+    AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatus.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatus.proto
new file mode 100644
index 0000000000000000000000000000000000000000..0cd7726c32c889264ecb474add5c437a432b7375
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatus.proto
@@ -0,0 +1,108 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalStatus";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum GlobalStatusProto {
+
+    /**
+    * Un known global status.
+    */
+    // Unknown
+    UnKnown = 0;
+
+    /**
+     * The Begin.
+     */
+    // PHASE 1: can accept new branch registering.
+    Begin = 1;
+
+    /**
+     * PHASE 2: Running Status: may be changed any time.
+     */
+    // Committing.
+    Committing = 2;
+
+    /**
+     * The Commit retrying.
+     */
+    // Retrying commit after a recoverable failure.
+    CommitRetrying = 3;
+
+    /**
+     * Rollbacking global status.
+     */
+    // Rollbacking
+    Rollbacking = 4;
+
+    /**
+     * The Rollback retrying.
+     */
+    // Retrying rollback after a recoverable failure.
+    RollbackRetrying = 5;
+
+    /**
+     * The Timeout rollbacking.
+     */
+    // Rollbacking since timeout
+    TimeoutRollbacking = 6;
+
+    /**
+     * The Timeout rollback retrying.
+     */
+    // Retrying rollback (since timeout) after a recoverable failure.
+    TimeoutRollbackRetrying = 7;
+
+    /**
+     * All branches can be async committed. The committing is NOT done yet, but it can be seen as committed for TM/RM
+     * client.
+     */
+    AsyncCommitting = 8;
+
+    /**
+     * PHASE 2: Final Status: will NOT change any more.
+     */
+    // Finally: global transaction is successfully committed.
+    Committed = 9;
+
+    /**
+     * The Commit failed.
+     */
+    // Finally: failed to commit
+    CommitFailed = 10;
+
+    /**
+     * The Rollbacked.
+     */
+    // Finally: global transaction is successfully rollbacked.
+    Rollbacked = 11;
+
+    /**
+     * The Rollback failed.
+     */
+    // Finally: failed to rollback
+    RollbackFailed = 12;
+
+    /**
+     * The Timeout rollbacked.
+     */
+    // Finally: global transaction is successfully rollbacked since timeout.
+    TimeoutRollbacked = 13;
+
+    /**
+     * The Timeout rollback failed.
+     */
+    // Finally: failed to rollback since timeout
+    TimeoutRollbackFailed = 14;
+
+    /**
+     * The Finished.
+     */
+    // Not managed in session MAP any more
+    Finished = 15;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..4b223c9a042152b50b799165655868dae79d3cc4
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusRequest.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalStatusRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalStatusRequestProto {
+    AbstractGlobalEndRequestProto abstractGlobalEndRequest = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..db208620c1da34a5d5ab05fe311e17fad0c2bdc7
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/globalStatusResponse.proto
@@ -0,0 +1,13 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractGlobalEndResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "GlobalStatusResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+message GlobalStatusResponseProto {
+    AbstractGlobalEndResponseProto abstractGlobalEndResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/heartbeatMessage.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/heartbeatMessage.proto
new file mode 100644
index 0000000000000000000000000000000000000000..e837fc0991a809e92885ddf4e1f8dcd20cad98af
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/heartbeatMessage.proto
@@ -0,0 +1,12 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "HeartbeatMessage";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message HeartbeatMessageProto {
+    bool ping = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedResultMessage.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedResultMessage.proto
new file mode 100644
index 0000000000000000000000000000000000000000..04ec928bef998ca2f41bd86ebf5d6e3f910e3185
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedResultMessage.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractMessage.proto";
+import "google/protobuf/any.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "MergedResultMessage";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message MergedResultMessageProto {
+    AbstractMessageProto abstractMessage=1;
+    repeated google.protobuf.Any msgs = 2;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedWarpMessage.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedWarpMessage.proto
new file mode 100644
index 0000000000000000000000000000000000000000..1cfb779c29ad71fe9abfb1166e7e63ecaabb6fff
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/mergedWarpMessage.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractMessage.proto";
+import "google/protobuf/any.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "MergedWarpMessage";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message MergedWarpMessageProto {
+    AbstractMessageProto abstractMessage=1;
+    repeated google.protobuf.Any msgs = 2;
+    repeated int32 msgIds=3;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/messageType.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/messageType.proto
new file mode 100644
index 0000000000000000000000000000000000000000..4f662d8766ff614523b76736a1f5dd4f92a80bf0
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/messageType.proto
@@ -0,0 +1,109 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "MessageType";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum MessageTypeProto {
+
+    TYPE_GLOBAL_PRESERVED = 0;
+
+    TYPE_GLOBAL_BEGIN = 1;
+
+    TYPE_GLOBAL_BEGIN_RESULT = 2;
+    /**
+     * The constant TYPE_GLOBAL_COMMIT.
+     */
+    TYPE_GLOBAL_COMMIT = 7;
+    /**
+     * The constant TYPE_GLOBAL_COMMIT_RESULT.
+     */
+    TYPE_GLOBAL_COMMIT_RESULT = 8;
+    /**
+     * The constant TYPE_GLOBAL_ROLLBACK.
+     */
+    TYPE_GLOBAL_ROLLBACK = 9;
+    /**
+     * The constant TYPE_GLOBAL_ROLLBACK_RESULT.
+     */
+    TYPE_GLOBAL_ROLLBACK_RESULT = 10;
+    /**
+     * The constant TYPE_GLOBAL_STATUS.
+     */
+    TYPE_GLOBAL_STATUS = 15;
+    /**
+     * The constant TYPE_GLOBAL_STATUS_RESULT.
+     */
+    TYPE_GLOBAL_STATUS_RESULT = 16;
+    /**
+     * The constant TYPE_GLOBAL_LOCK_QUERY.
+     */
+    TYPE_GLOBAL_LOCK_QUERY = 21;
+    /**
+     * The constant TYPE_GLOBAL_LOCK_QUERY_RESULT.
+     */
+    TYPE_GLOBAL_LOCK_QUERY_RESULT = 22;
+
+    /**
+     * The constant TYPE_BRANCH_COMMIT.
+     */
+    TYPE_BRANCH_COMMIT = 3;
+    /**
+     * The constant TYPE_BRANCH_COMMIT_RESULT.
+     */
+    TYPE_BRANCH_COMMIT_RESULT = 4;
+    /**
+     * The constant TYPE_BRANCH_ROLLBACK.
+     */
+    TYPE_BRANCH_ROLLBACK = 5;
+    /**
+     * The constant TYPE_BRANCH_ROLLBACK_RESULT.
+     */
+    TYPE_BRANCH_ROLLBACK_RESULT = 6;
+    /**
+     * The constant TYPE_BRANCH_REGISTER.
+     */
+    TYPE_BRANCH_REGISTER = 11;
+    /**
+     * The constant TYPE_BRANCH_REGISTER_RESULT.
+     */
+    TYPE_BRANCH_REGISTER_RESULT = 12;
+    /**
+     * The constant TYPE_BRANCH_STATUS_REPORT.
+     */
+    TYPE_BRANCH_STATUS_REPORT = 13;
+    /**
+     * The constant TYPE_BRANCH_STATUS_REPORT_RESULT.
+     */
+    TYPE_BRANCH_STATUS_REPORT_RESULT = 14;
+
+    /**
+     * The constant TYPE_SEATA_MERGE.
+     */
+    TYPE_SEATA_MERGE = 59;
+    /**
+     * The constant TYPE_SEATA_MERGE_RESULT.
+     */
+    TYPE_SEATA_MERGE_RESULT = 60;
+
+    /**
+     * The constant TYPE_REG_CLT.
+     */
+    TYPE_REG_CLT = 101;
+    /**
+     * The constant TYPE_REG_CLT_RESULT.
+     */
+    TYPE_REG_CLT_RESULT = 102;
+    /**
+     * The constant TYPE_REG_RM.
+     */
+    TYPE_REG_RM = 103;
+    /**
+     * The constant TYPE_REG_RM_RESULT.
+     */
+    TYPE_REG_RM_RESULT = 104;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..64fbfa642c1758118b364d4b8de4f1d331b084f8
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMRequest.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractIdentifyRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RegisterRMRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message RegisterRMRequestProto {
+    AbstractIdentifyRequestProto abstractIdentifyRequest = 1;
+    string resourceIds = 2;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..10e6b5e384bbadb32fc769bd2ef3a0d143539ad1
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerRMResponse.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractIdentifyResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RegisterRMResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message RegisterRMResponseProto {
+    AbstractIdentifyResponseProto abstractIdentifyResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMRequest.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMRequest.proto
new file mode 100644
index 0000000000000000000000000000000000000000..16cbf1f2b367b08cef9b2093f37d7a76abbdf898
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMRequest.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractIdentifyRequest.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RegisterTMRequest";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message RegisterTMRequestProto {
+    AbstractIdentifyRequestProto abstractIdentifyRequest = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMResponse.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMResponse.proto
new file mode 100644
index 0000000000000000000000000000000000000000..0bfb731e802acf25429d401874147c4b60be5a74
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/registerTMResponse.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+import "abstractIdentifyResponse.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RegisterTMResponse";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+message RegisterTMResponseProto {
+    AbstractIdentifyResponseProto abstractIdentifyResponse = 1;
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/resultCode.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/resultCode.proto
new file mode 100644
index 0000000000000000000000000000000000000000..dd40246efc2c4852adac1e528e93526c603145f2
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/resultCode.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "ResultCode";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum ResultCodeProto {
+
+    Failed = 0;
+
+    Success = 1;
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/transactionExceptionCode.proto b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/transactionExceptionCode.proto
new file mode 100644
index 0000000000000000000000000000000000000000..ddc9429640eabfb8f6d4fc603aed3a916735fae5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/main/resources/protobuf/io/seata/protocol/transcation/transactionExceptionCode.proto
@@ -0,0 +1,113 @@
+syntax = "proto3";
+
+package io.seata.protocol.protobuf;
+
+option java_multiple_files = true;
+option java_outer_classname = "TransactionExceptionCode";
+option java_package = "io.seata.codec.protobuf.generated";
+
+// PublishRequest is a publish request.
+enum TransactionExceptionCodeProto {
+
+    /**
+     * Unknown transaction exception code.
+     */
+    //
+    Unknown = 0;
+
+    /**
+     * Lock key conflict transaction exception code.
+     */
+    //
+    LockKeyConflict = 1;
+
+    /**
+     * Io transaction exception code.
+     */
+    //
+    IO = 2;
+
+    /**
+     * Branch rollback failed retriable transaction exception code.
+     */
+    //
+    BranchRollbackFailed_Retriable = 3;
+
+    /**
+     * Branch rollback failed unretriable transaction exception code.
+     */
+    //
+    BranchRollbackFailed_Unretriable = 4;
+
+    /**
+     * Branch register failed transaction exception code.
+     */
+    //
+    BranchRegisterFailed = 5;
+
+    /**
+     * Branch report failed transaction exception code.
+     */
+    //
+    BranchReportFailed = 6;
+
+    /**
+     * Lockable check failed transaction exception code.
+     */
+    //
+    LockableCheckFailed = 7;
+
+    /**
+     * Branch transaction not exist transaction exception code.
+     */
+    //
+    BranchTransactionNotExist = 8;
+
+    /**
+     * Global transaction not exist transaction exception code.
+     */
+    //
+    GlobalTransactionNotExist = 9;
+
+    /**
+     * Global transaction not active transaction exception code.
+     */
+    //
+    GlobalTransactionNotActive = 10;
+
+    /**
+     * Global transaction status invalid transaction exception code.
+     */
+    //
+    GlobalTransactionStatusInvalid = 11;
+
+    /**
+     * Failed to send branch commit request transaction exception code.
+     */
+    //
+    FailedToSendBranchCommitRequest = 12;
+
+    /**
+     * Failed to send branch rollback request transaction exception code.
+     */
+    //
+    FailedToSendBranchRollbackRequest = 13;
+
+    /**
+     * Failed to add branch transaction exception code.
+     */
+    //
+    FailedToAddBranch = 14;
+
+    /**
+  *  Failed to lock global transaction exception code.
+  */
+    FailedLockGlobalTranscation = 15;
+
+    /**
+     * FailedWriteSession
+     */
+    FailedWriteSession = 16;
+
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec556f0665fb837468d17e17ac1d183a685669ba
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitRequestConvertorTest.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.BranchCommitRequestProto;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchCommitRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchCommitRequest branchCommitRequest = new BranchCommitRequest();
+        branchCommitRequest.setBranchType(BranchType.AT);
+        branchCommitRequest.setXid("xid");
+        branchCommitRequest.setResourceId("resourceId");
+        branchCommitRequest.setBranchId(123);
+        branchCommitRequest.setApplicationData("app");
+
+        BranchCommitRequestConvertor branchCommitRequestConvertor = new BranchCommitRequestConvertor();
+        BranchCommitRequestProto proto = branchCommitRequestConvertor.convert2Proto(
+            branchCommitRequest);
+        BranchCommitRequest realRequest = branchCommitRequestConvertor.convert2Model(proto);
+
+        assertThat(realRequest.getTypeCode()).isEqualTo(branchCommitRequest.getTypeCode());
+        assertThat(realRequest.getBranchType()).isEqualTo(branchCommitRequest.getBranchType());
+        assertThat(realRequest.getXid()).isEqualTo(branchCommitRequest.getXid());
+        assertThat(realRequest.getResourceId()).isEqualTo(branchCommitRequest.getResourceId());
+        assertThat(realRequest.getBranchId()).isEqualTo(branchCommitRequest.getBranchId());
+        assertThat(realRequest.getApplicationData()).isEqualTo(branchCommitRequest.getApplicationData());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..89580441653e59f175eb4de9cdd30f66e4b8f260
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchCommitResponseConvertorTest.java
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.BranchCommitResponseProto;
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchCommitResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchCommitResponse branchCommitResponse = new BranchCommitResponse();
+        branchCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+        branchCommitResponse.setResultCode(ResultCode.Success);
+        branchCommitResponse.setMsg("xx");
+        branchCommitResponse.setXid("xid");
+        branchCommitResponse.setBranchStatus(BranchStatus.PhaseTwo_Rollbacked);
+        branchCommitResponse.setBranchId(123);
+
+        BranchCommitResponseConvertor convertor = new BranchCommitResponseConvertor();
+        BranchCommitResponseProto proto = convertor.convert2Proto(branchCommitResponse);
+        BranchCommitResponse real = convertor.convert2Model(proto);
+
+        assertThat(real.getTypeCode()).isEqualTo(branchCommitResponse.getTypeCode());
+        assertThat(real.getMsg()).isEqualTo(branchCommitResponse.getMsg());
+        assertThat(real.getXid()).isEqualTo(branchCommitResponse.getXid());
+        assertThat(real.getTransactionExceptionCode()).isEqualTo(branchCommitResponse.getTransactionExceptionCode());
+        assertThat(real.getBranchStatus()).isEqualTo(branchCommitResponse.getBranchStatus());
+        assertThat(real.getResultCode()).isEqualTo(branchCommitResponse.getResultCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..915ed14e9ce6cc58717fab5bcd8beb018709316e
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterRequestConvertorTest.java
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.BranchRegisterRequestProto;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRegisterRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchRegisterRequest branchRegisterRequest = new BranchRegisterRequest();
+        branchRegisterRequest.setApplicationData("data");
+        branchRegisterRequest.setBranchType(BranchType.AT);
+        branchRegisterRequest.setLockKey("localKey");
+        branchRegisterRequest.setResourceId("resourceId");
+        branchRegisterRequest.setXid("xid");
+
+        BranchRegisterRequestConvertor convertor = new BranchRegisterRequestConvertor();
+        BranchRegisterRequestProto proto = convertor.convert2Proto(
+            branchRegisterRequest);
+        BranchRegisterRequest real = convertor.convert2Model(proto);
+
+        assertThat(real.getTypeCode()).isEqualTo(branchRegisterRequest.getTypeCode());
+        assertThat(real.getApplicationData()).isEqualTo(branchRegisterRequest.getApplicationData());
+        assertThat(real.getXid()).isEqualTo(branchRegisterRequest.getXid());
+        assertThat(real.getBranchType()).isEqualTo(branchRegisterRequest.getBranchType());
+        assertThat(real.getLockKey()).isEqualTo(branchRegisterRequest.getLockKey());
+        assertThat(real.getResourceId()).isEqualTo(branchRegisterRequest.getResourceId());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..cea9cae6a30de461d38a2b1f32819377ad3e3205
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRegisterResponseConvertorTest.java
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.BranchRegisterResponseProto;
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRegisterResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchRegisterResponse branchRegisterResponse = new BranchRegisterResponse();
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotActive);
+        branchRegisterResponse.setResultCode(ResultCode.Failed);
+        branchRegisterResponse.setMsg("msg");
+        branchRegisterResponse.setBranchId(123);
+
+        BranchRegisterResponseConvertor convertor = new BranchRegisterResponseConvertor();
+        BranchRegisterResponseProto proto = convertor.convert2Proto(
+            branchRegisterResponse);
+
+        BranchRegisterResponse real = convertor.convert2Model(proto);
+
+        assertThat(real.getTransactionExceptionCode()).isEqualTo(branchRegisterResponse.getTransactionExceptionCode());
+        assertThat(real.getResultCode()).isEqualTo(branchRegisterResponse.getResultCode());
+        assertThat(real.getMsg()).isEqualTo(branchRegisterResponse.getMsg());
+        assertThat(real.getBranchId()).isEqualTo(branchRegisterResponse.getBranchId());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a0878df78094fe35223fc7f1191ed5216aa052c
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportRequestConvertorTest.java
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchStatus;
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.BranchReportRequestProto;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchReportRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchReportRequest branchReportRequest = new BranchReportRequest();
+
+        branchReportRequest.setApplicationData("data");
+        branchReportRequest.setBranchId(123);
+        branchReportRequest.setResourceId("resourceId");
+        branchReportRequest.setXid("xid");
+        branchReportRequest.setBranchType(
+            BranchType.AT);
+        branchReportRequest.setStatus(BranchStatus.PhaseOne_Done);
+        BranchReportRequestConvertor convertor = new BranchReportRequestConvertor();
+        BranchReportRequestProto proto = convertor.convert2Proto(branchReportRequest);
+        BranchReportRequest real = convertor.convert2Model(proto);
+
+        assertThat(real.getBranchType()).isEqualTo(branchReportRequest.getBranchType());
+        assertThat(real.getXid()).isEqualTo(branchReportRequest.getXid());
+        assertThat(real.getResourceId()).isEqualTo(branchReportRequest.getResourceId());
+        assertThat(real.getBranchId()).isEqualTo(branchReportRequest.getBranchId());
+        assertThat(real.getApplicationData()).isEqualTo(branchReportRequest.getApplicationData());
+        assertThat(real.getStatus()).isEqualTo(branchReportRequest.getStatus());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..65d7520bfcf90b1f0d5f0a13a9bb64c00c799f52
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchReportResponseConvertorTest.java
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.BranchReportResponseProto;
+import io.seata.core.protocol.transaction.BranchReportResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchReportResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchReportResponse branchReportResponse = new BranchReportResponse();
+        branchReportResponse.setMsg("msg");
+        branchReportResponse.setResultCode(ResultCode.Failed);
+        branchReportResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotExist);
+        BranchReportResponseConvertor convertor = new BranchReportResponseConvertor();
+        BranchReportResponseProto proto = convertor.convert2Proto(branchReportResponse);
+        BranchReportResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(branchReportResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(branchReportResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(branchReportResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(branchReportResponse.getTransactionExceptionCode());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..373654fa3d37a8391168a244e4f72f9953ffd68a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackRequestConvertorTest.java
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.BranchRollbackRequestProto;
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRollbackRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchRollbackRequest branchRegisterRequest = new BranchRollbackRequest();
+        branchRegisterRequest.setApplicationData("data");
+        branchRegisterRequest.setBranchType(BranchType.AT);
+        branchRegisterRequest.setResourceId("resourceId");
+        branchRegisterRequest.setXid("xid");
+        branchRegisterRequest.setBranchId(123);
+
+        BranchRollbackRequestConvertor convertor = new BranchRollbackRequestConvertor();
+        BranchRollbackRequestProto proto = convertor.convert2Proto(
+            branchRegisterRequest);
+
+        BranchRollbackRequest real = convertor.convert2Model(proto);
+
+        assertThat((real.getTypeCode())).isEqualTo(branchRegisterRequest.getTypeCode());
+        assertThat((real.getApplicationData())).isEqualTo(branchRegisterRequest.getApplicationData());
+        assertThat((real.getBranchType())).isEqualTo(branchRegisterRequest.getBranchType());
+        assertThat((real.getXid())).isEqualTo(branchRegisterRequest.getXid());
+        assertThat((real.getResourceId())).isEqualTo(branchRegisterRequest.getResourceId());
+        assertThat((real.getBranchId())).isEqualTo(branchRegisterRequest.getBranchId());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4edf9da0a37f145136aea777aa37073209981288
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/BranchRollbackResponseConvertorTest.java
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.BranchRollbackResponseProto;
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class BranchRollbackResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        BranchRollbackResponse branchRollbackResponse = new BranchRollbackResponse();
+        branchRollbackResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+        branchRollbackResponse.setResultCode(ResultCode.Success);
+        branchRollbackResponse.setMsg("xx");
+        branchRollbackResponse.setXid("xid");
+        branchRollbackResponse.setBranchStatus(BranchStatus.PhaseTwo_Rollbacked);
+        branchRollbackResponse.setBranchId(123);
+
+        BranchRollbackResponseConvertor convertor = new BranchRollbackResponseConvertor();
+        BranchRollbackResponseProto proto = convertor.convert2Proto(
+            branchRollbackResponse);
+        BranchRollbackResponse real = convertor.convert2Model(proto);
+
+        assertThat(real.getTypeCode()).isEqualTo(branchRollbackResponse.getTypeCode());
+        assertThat(real.getMsg()).isEqualTo(branchRollbackResponse.getMsg());
+        assertThat(real.getXid()).isEqualTo(branchRollbackResponse.getXid());
+        assertThat(real.getTransactionExceptionCode()).isEqualTo(branchRollbackResponse.getTransactionExceptionCode());
+        assertThat(real.getBranchStatus()).isEqualTo(branchRollbackResponse.getBranchStatus());
+        assertThat(real.getResultCode()).isEqualTo(branchRollbackResponse.getResultCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7745cbf8fe548d2556ca21b6d019068995301fec
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginRequestConvertorTest.java
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.GlobalBeginRequestProto;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalBeginRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+        globalBeginRequest.setTimeout(3000);
+        globalBeginRequest.setTransactionName("taa");
+
+        GlobalBeginRequestConvertor convertor = new GlobalBeginRequestConvertor();
+        GlobalBeginRequestProto proto = convertor.convert2Proto(globalBeginRequest);
+        GlobalBeginRequest real = convertor.convert2Model(proto);
+
+        assertThat(real.getTypeCode()).isEqualTo(globalBeginRequest.getTypeCode());
+        assertThat(real.getTimeout()).isEqualTo(globalBeginRequest.getTimeout());
+        assertThat(real.getTransactionName()).isEqualTo(globalBeginRequest.getTransactionName());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cf5cea690b0044f4539c779b47c61e54800e635
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalBeginResponseConvertorTest.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.GlobalBeginResponseProto;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalBeginResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalBeginResponse globalBeginResponse = new GlobalBeginResponse();
+
+        globalBeginResponse.setResultCode(ResultCode.Failed);
+        globalBeginResponse.setMsg("msg");
+        globalBeginResponse.setExtraData("extraData");
+        globalBeginResponse.setXid("xid");
+        globalBeginResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchRollbackFailed_Retriable);
+
+        GlobalBeginResponseConvertor convertor = new GlobalBeginResponseConvertor();
+        GlobalBeginResponseProto proto = convertor.convert2Proto(globalBeginResponse);
+        GlobalBeginResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalBeginResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(globalBeginResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(globalBeginResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(globalBeginResponse.getTransactionExceptionCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fa286656471e91de0d328d74d3bee1e4357795b
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitRequestConvertorTest.java
@@ -0,0 +1,43 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.GlobalCommitRequestProto;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalCommitRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalCommitRequest globalCommitRequest = new GlobalCommitRequest();
+        globalCommitRequest.setExtraData("extraData");
+        globalCommitRequest.setXid("xid");
+
+        GlobalCommitRequestConvertor convertor = new GlobalCommitRequestConvertor();
+        GlobalCommitRequestProto proto = convertor.convert2Proto(globalCommitRequest);
+        GlobalCommitRequest real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalCommitRequest.getTypeCode());
+        assertThat((real.getXid())).isEqualTo(globalCommitRequest.getXid());
+        assertThat((real.getExtraData())).isEqualTo(globalCommitRequest.getExtraData());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2433a4f972e4fbd4d93734b0d8ff1d8658ee129
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalCommitResponseConvertorTest.java
@@ -0,0 +1,48 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.GlobalCommitResponseProto;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalCommitResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+        globalCommitResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalCommitResponse.setMsg("msg");
+        globalCommitResponse.setResultCode(ResultCode.Failed);
+        globalCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchRegisterFailed);
+        GlobalCommitResponseConvertor convertor = new GlobalCommitResponseConvertor();
+        GlobalCommitResponseProto proto = convertor.convert2Proto(globalCommitResponse);
+        GlobalCommitResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalCommitResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(globalCommitResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(globalCommitResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(globalCommitResponse.getTransactionExceptionCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaa25ab23e5aab94b2787e5e5e6ca3eceef409e8
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryRequestConvertorTest.java
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.model.BranchType;
+import io.seata.codec.protobuf.generated.GlobalLockQueryRequestProto;
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalLockQueryRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalLockQueryRequest globalLockQueryRequest = new GlobalLockQueryRequest();
+        globalLockQueryRequest.setApplicationData("data");
+        globalLockQueryRequest.setBranchType(BranchType.AT);
+        globalLockQueryRequest.setLockKey("localKey");
+        globalLockQueryRequest.setResourceId("resourceId");
+        globalLockQueryRequest.setXid("xid");
+
+        GlobalLockQueryRequestConvertor convertor = new GlobalLockQueryRequestConvertor();
+        GlobalLockQueryRequestProto proto = convertor.convert2Proto(
+            globalLockQueryRequest);
+        GlobalLockQueryRequest real = convertor.convert2Model(proto);
+
+        assertThat(real.getTypeCode()).isEqualTo(globalLockQueryRequest.getTypeCode());
+        assertThat(real.getApplicationData()).isEqualTo(globalLockQueryRequest.getApplicationData());
+        assertThat(real.getXid()).isEqualTo(globalLockQueryRequest.getXid());
+        assertThat(real.getBranchType()).isEqualTo(globalLockQueryRequest.getBranchType());
+        assertThat(real.getLockKey()).isEqualTo(globalLockQueryRequest.getLockKey());
+        assertThat(real.getResourceId()).isEqualTo(globalLockQueryRequest.getResourceId());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea9d9e088f6ba258d456c00d81713d1f336352b6
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalLockQueryResponseConvertorTest.java
@@ -0,0 +1,49 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.GlobalLockQueryResponseProto;
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalLockQueryResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalLockQueryResponse globalLockQueryResponse = new GlobalLockQueryResponse();
+        globalLockQueryResponse.setLockable(true);
+        globalLockQueryResponse.setMsg("msg");
+        globalLockQueryResponse.setResultCode(ResultCode.Failed);
+        globalLockQueryResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotActive);
+        GlobalLockQueryResponseConvertor convertor = new GlobalLockQueryResponseConvertor();
+        GlobalLockQueryResponseProto proto = convertor.convert2Proto(
+            globalLockQueryResponse);
+        GlobalLockQueryResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalLockQueryResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(globalLockQueryResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(globalLockQueryResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(
+            globalLockQueryResponse.getTransactionExceptionCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f5855193352ef08fdd86e35e98c5b473e4f6021
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackRequestConvertorTest.java
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.GlobalRollbackRequestProto;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalRollbackRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
+        globalRollbackRequest.setExtraData("extraData");
+        globalRollbackRequest.setXid("xid");
+
+        GlobalRollbackRequestConvertor convertor = new GlobalRollbackRequestConvertor();
+        GlobalRollbackRequestProto proto = convertor.convert2Proto(
+            globalRollbackRequest);
+        GlobalRollbackRequest real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalRollbackRequest.getTypeCode());
+        assertThat((real.getXid())).isEqualTo(globalRollbackRequest.getXid());
+        assertThat((real.getExtraData())).isEqualTo(globalRollbackRequest.getExtraData());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebd54909fe65cab4c25165d86cf4b61b30b624bb
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalRollbackResponseConvertorTest.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.GlobalRollbackResponseProto;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalRollbackResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalRollbackResponse globalRollbackResponse = new GlobalRollbackResponse();
+        globalRollbackResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalRollbackResponse.setMsg("msg");
+        globalRollbackResponse.setResultCode(ResultCode.Failed);
+        globalRollbackResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchRegisterFailed);
+        GlobalRollbackResponseConvertor convertor = new GlobalRollbackResponseConvertor();
+        GlobalRollbackResponseProto proto = convertor.convert2Proto(
+            globalRollbackResponse);
+        GlobalRollbackResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalRollbackResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(globalRollbackResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(globalRollbackResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(
+            globalRollbackResponse.getTransactionExceptionCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1b2466f283946a3c37f8d3fc3a7b95fd98c0e61
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusRequestConvertorTest.java
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.codec.protobuf.generated.GlobalStatusRequestProto;
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalStatusRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalStatusRequest globalStatusRequest = new GlobalStatusRequest();
+        globalStatusRequest.setExtraData("extraData");
+        globalStatusRequest.setXid("xid");
+        GlobalStatusRequestConvertor convertor = new GlobalStatusRequestConvertor();
+        GlobalStatusRequestProto proto = convertor.convert2Proto(
+            globalStatusRequest);
+        GlobalStatusRequest real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalStatusRequest.getTypeCode());
+        assertThat((real.getXid())).isEqualTo(globalStatusRequest.getXid());
+        assertThat((real.getExtraData())).isEqualTo(globalStatusRequest.getExtraData());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..091f06dc320445de8d0421f17db0332d39abe2d5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/GlobalStatusResponseConvertorTest.java
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.GlobalStatusResponseProto;
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class GlobalStatusResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        GlobalStatusResponse globalStatusResponse = new GlobalStatusResponse();
+        globalStatusResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalStatusResponse.setMsg("msg");
+        globalStatusResponse.setResultCode(ResultCode.Failed);
+        globalStatusResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchRegisterFailed);
+        GlobalStatusResponseConvertor convertor = new GlobalStatusResponseConvertor();
+        GlobalStatusResponseProto proto = convertor.convert2Proto(
+            globalStatusResponse);
+        GlobalStatusResponse real = convertor.convert2Model(proto);
+        assertThat((real.getTypeCode())).isEqualTo(globalStatusResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(globalStatusResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(globalStatusResponse.getResultCode());
+        assertThat((real.getTransactionExceptionCode())).isEqualTo(
+            globalStatusResponse.getTransactionExceptionCode());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6b2c7626f53f2f2315d9f6a1ada6b2f549a6a3f
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/HeartbeatMessageConvertorTest.java
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.HeartbeatMessage;
+import io.seata.codec.protobuf.generated.HeartbeatMessageProto;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class HeartbeatMessageConvertorTest {
+
+    @Test
+    public void test() {
+        HeartbeatMessage heartbeatMessage = HeartbeatMessage.PING;
+        HeartbeatMessageConvertor convertor = new HeartbeatMessageConvertor();
+        HeartbeatMessageProto proto = convertor.convert2Proto(heartbeatMessage);
+        HeartbeatMessage real = convertor.convert2Model(proto);
+        assertThat(real).isEqualTo(heartbeatMessage);
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeMessageConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeMessageConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7a790597bc7f010df28a0d8eb293ef2dd11a6177
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeMessageConvertorTest.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import java.util.ArrayList;
+
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+import io.seata.codec.protobuf.generated.MergedWarpMessageProto;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class MergeMessageConvertorTest {
+
+    @Test
+    public void test() {
+        MergedWarpMessage mergedWarpMessage = new MergedWarpMessage();
+        final ArrayList<AbstractMessage> msgs = new ArrayList<>();
+        final GlobalBeginRequest globalBeginRequest = buildGlobalBeginRequest();
+        msgs.add(globalBeginRequest);
+        mergedWarpMessage.msgs = msgs;
+
+        MergedWarpMessageConvertor pbConvertor = new MergedWarpMessageConvertor();
+        MergedWarpMessageProto globalBeginRequestProto = pbConvertor.convert2Proto(
+            mergedWarpMessage);
+
+        MergedWarpMessage model = pbConvertor.convert2Model(globalBeginRequestProto);
+
+        GlobalBeginRequest decodeModel = (GlobalBeginRequest)model.msgs.get(0);
+        assertThat(decodeModel.getTransactionName()).isEqualTo(
+            globalBeginRequest.getTransactionName());
+        assertThat(decodeModel.getTimeout()).isEqualTo(globalBeginRequest.getTimeout());
+        assertThat(
+            decodeModel.getTypeCode()).isEqualTo(globalBeginRequest.getTypeCode());
+
+    }
+
+    private GlobalBeginRequest buildGlobalBeginRequest() {
+        final GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+        globalBeginRequest.setTransactionName("xx");
+        globalBeginRequest.setTimeout(3000);
+        return globalBeginRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d13e67071b45320f043bd2d0ca3757b4d4460f94
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/MergeResultMessageConvertorTest.java
@@ -0,0 +1,59 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.MergeResultMessage;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.MergedResultMessageProto;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class MergeResultMessageConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        MergeResultMessage mergeResultMessage = new MergeResultMessage();
+        AbstractResultMessage[] msgs = new AbstractResultMessage[1];
+        final GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+        globalCommitResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalCommitResponse.setMsg("msg");
+        globalCommitResponse.setResultCode(ResultCode.Failed);
+        globalCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchRegisterFailed);
+        msgs[0] = globalCommitResponse;
+        mergeResultMessage.setMsgs(msgs);
+
+        MergeResultMessageConvertor convertor = new MergeResultMessageConvertor();
+        MergedResultMessageProto proto = convertor.convert2Proto(mergeResultMessage);
+        MergeResultMessage real = convertor.convert2Model(proto);
+
+        GlobalCommitResponse realObj = (GlobalCommitResponse)real.getMsgs()[0];
+
+        assertThat((realObj.getTypeCode())).isEqualTo(globalCommitResponse.getTypeCode());
+        assertThat((realObj.getMsg())).isEqualTo(globalCommitResponse.getMsg());
+        assertThat((realObj.getResultCode())).isEqualTo(globalCommitResponse.getResultCode());
+        assertThat((realObj.getTransactionExceptionCode())).isEqualTo(
+            globalCommitResponse.getTransactionExceptionCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d3e57e4903e1f215c8b601f23bb512d19e2ef73
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMRequestConvertorTest.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.RegisterRMRequest;
+import io.seata.codec.protobuf.generated.RegisterRMRequestProto;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterRMRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+        RegisterRMRequest registerRMRequest = new RegisterRMRequest();
+        registerRMRequest.setResourceIds("res1");
+        registerRMRequest.setVersion("123");
+        registerRMRequest.setTransactionServiceGroup("group");
+        registerRMRequest.setExtraData("extraData");
+        registerRMRequest.setApplicationId("appId");
+
+        RegisterRMRequestConvertor convertor = new RegisterRMRequestConvertor();
+        RegisterRMRequestProto proto = convertor.convert2Proto(registerRMRequest);
+        RegisterRMRequest real = convertor.convert2Model(proto);
+
+        assertThat((real.getTypeCode())).isEqualTo(registerRMRequest.getTypeCode());
+        assertThat((real.getResourceIds())).isEqualTo(registerRMRequest.getResourceIds());
+        assertThat((real.getVersion())).isEqualTo(registerRMRequest.getVersion());
+        assertThat((real.getTransactionServiceGroup())).isEqualTo(registerRMRequest.getTransactionServiceGroup());
+        assertThat((real.getExtraData())).isEqualTo(registerRMRequest.getExtraData());
+        assertThat((real.getApplicationId())).isEqualTo(registerRMRequest.getApplicationId());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..170c42e1733cbad25db9e8efbdb1b018ccc787d5
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterRMResponseConvertorTest.java
@@ -0,0 +1,51 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.RegisterRMResponse;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.RegisterRMResponseProto;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterRMResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        RegisterRMResponse registerRMResponse = new RegisterRMResponse();
+        registerRMResponse.setResultCode(ResultCode.Failed);
+        registerRMResponse.setMsg("msg");
+        registerRMResponse.setIdentified(true);
+        registerRMResponse.setVersion("11");
+        registerRMResponse.setExtraData("extraData");
+        RegisterRMResponseConvertor convertor = new RegisterRMResponseConvertor();
+        RegisterRMResponseProto proto = convertor.convert2Proto(registerRMResponse);
+        RegisterRMResponse real = convertor.convert2Model(proto);
+
+        assertThat((real.getTypeCode())).isEqualTo(registerRMResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(registerRMResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(registerRMResponse.getResultCode());
+        assertThat((real.isIdentified())).isEqualTo(registerRMResponse.isIdentified());
+        assertThat((real.getVersion())).isEqualTo(registerRMResponse.getVersion());
+        assertThat((real.getExtraData())).isEqualTo(registerRMResponse.getExtraData());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e28f8357f671c1817f9930bf7b5fd4471152ffa
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMRequestConvertorTest.java
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.RegisterTMRequest;
+import io.seata.codec.protobuf.generated.RegisterTMRequestProto;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterTMRequestConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        RegisterTMRequest registerRMRequest = new RegisterTMRequest();
+        registerRMRequest.setVersion("123");
+        registerRMRequest.setTransactionServiceGroup("group");
+        registerRMRequest.setExtraData("extraData");
+        registerRMRequest.setApplicationId("appId");
+        RegisterTMRequestConvertor convertor = new RegisterTMRequestConvertor();
+        RegisterTMRequestProto proto = convertor.convert2Proto(registerRMRequest);
+        RegisterTMRequest real = convertor.convert2Model(proto);
+
+        assertThat((real.getTypeCode())).isEqualTo(registerRMRequest.getTypeCode());
+        assertThat((real.getVersion())).isEqualTo(registerRMRequest.getVersion());
+        assertThat((real.getTransactionServiceGroup())).isEqualTo(registerRMRequest.getTransactionServiceGroup());
+        assertThat((real.getExtraData())).isEqualTo(registerRMRequest.getExtraData());
+        assertThat((real.getApplicationId())).isEqualTo(registerRMRequest.getApplicationId());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertorTest.java b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..46ef1368b75f7b583d5853323239a429c7d1f39a
--- /dev/null
+++ b/codec/seata-codec-protobuf/src/test/java/io/seata/codec/protobuf/convertor/RegisterTMResponseConvertorTest.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.protobuf.convertor;
+
+import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.protocol.ResultCode;
+import io.seata.codec.protobuf.generated.RegisterTMResponseProto;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author leizhiyuan
+ */
+public class RegisterTMResponseConvertorTest {
+
+    @Test
+    public void convert2Proto() {
+
+        RegisterTMResponse registerRMResponse = new RegisterTMResponse();
+        registerRMResponse.setResultCode(ResultCode.Failed);
+        registerRMResponse.setMsg("msg");
+        registerRMResponse.setIdentified(true);
+        registerRMResponse.setVersion("11");
+        registerRMResponse.setExtraData("extraData");
+        RegisterTMResponseConvertor convertor = new RegisterTMResponseConvertor();
+        RegisterTMResponseProto proto = convertor.convert2Proto(registerRMResponse);
+        RegisterTMResponse real = convertor.convert2Model(proto);
+
+        assertThat((real.getTypeCode())).isEqualTo(registerRMResponse.getTypeCode());
+        assertThat((real.getMsg())).isEqualTo(registerRMResponse.getMsg());
+        assertThat((real.getResultCode())).isEqualTo(registerRMResponse.getResultCode());
+        assertThat((real.isIdentified())).isEqualTo(registerRMResponse.isIdentified());
+        assertThat((real.getVersion())).isEqualTo(registerRMResponse.getVersion());
+        assertThat((real.getExtraData())).isEqualTo(registerRMResponse.getExtraData());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/pom.xml b/codec/seata-codec-seata/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06de027577cb89f0abcb42eee5913e4f655aabda
--- /dev/null
+++ b/codec/seata-codec-seata/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.seata</groupId>
+        <artifactId>seata-codec</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>seata-codec-seata</artifactId>
+    <packaging>jar</packaging>
+    <name>seata-codec-seata ${project.version}</name>
+    <dependencies>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageCodecFactory.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageCodecFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..9784470414d34034d26b915328941127d9618cf1
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageCodecFactory.java
@@ -0,0 +1,391 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata;
+
+import io.seata.codec.seata.protocol.MergeResultMessageCodec;
+import io.seata.codec.seata.protocol.MergedWarpMessageCodec;
+import io.seata.codec.seata.protocol.RegisterRMRequestCodec;
+import io.seata.codec.seata.protocol.RegisterRMResponseCodec;
+import io.seata.codec.seata.protocol.RegisterTMRequestCodec;
+import io.seata.codec.seata.protocol.RegisterTMResponseCodec;
+import io.seata.codec.seata.protocol.transaction.BranchCommitRequestCodec;
+import io.seata.codec.seata.protocol.transaction.BranchCommitResponseCodec;
+import io.seata.codec.seata.protocol.transaction.BranchRegisterRequestCodec;
+import io.seata.codec.seata.protocol.transaction.BranchRegisterResponseCodec;
+import io.seata.codec.seata.protocol.transaction.BranchReportRequestCodec;
+import io.seata.codec.seata.protocol.transaction.BranchReportResponseCodec;
+import io.seata.codec.seata.protocol.transaction.BranchRollbackRequestCodec;
+import io.seata.codec.seata.protocol.transaction.BranchRollbackResponseCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalBeginRequestCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalBeginResponseCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalCommitRequestCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalCommitResponseCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalLockQueryRequestCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalLockQueryResponseCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalRollbackRequestCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalRollbackResponseCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalStatusRequestCodec;
+import io.seata.codec.seata.protocol.transaction.GlobalStatusResponseCodec;
+import io.seata.core.protocol.AbstractIdentifyRequest;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.MergeResultMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+import io.seata.core.protocol.MessageType;
+import io.seata.core.protocol.RegisterRMRequest;
+import io.seata.core.protocol.RegisterRMResponse;
+import io.seata.core.protocol.RegisterTMRequest;
+import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.protocol.transaction.AbstractBranchEndRequest;
+import io.seata.core.protocol.transaction.AbstractGlobalEndRequest;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+import io.seata.core.protocol.transaction.BranchReportResponse;
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * The type Message codec factory.
+ *
+ * @author zhangsen
+ */
+public class MessageCodecFactory {
+
+    /**
+     * The constant UTF8.
+     */
+    protected static final Charset UTF8 = Charset.forName("utf-8");
+
+    /**
+     * Get message codec message codec.
+     *
+     * @param abstractMessage the abstract message
+     * @return the message codec
+     */
+    public static MessageSeataCodec getMessageCodec(AbstractMessage abstractMessage){
+        return getMessageCodec(abstractMessage.getTypeCode());
+    }
+
+    /**
+     * Gets msg instance by code.
+     *
+     * @param typeCode the type code
+     * @return the msg instance by code
+     */
+    public static MessageSeataCodec getMessageCodec(short typeCode) {
+        MessageSeataCodec msgCodec = null;
+        switch (typeCode) {
+            case MessageType.TYPE_SEATA_MERGE:
+                msgCodec = new MergedWarpMessageCodec();
+                break;
+            case MessageType.TYPE_SEATA_MERGE_RESULT:
+                msgCodec = new MergeResultMessageCodec();
+                break;
+            case MessageType.TYPE_REG_CLT:
+                msgCodec = new RegisterTMRequestCodec();
+                break;
+            case MessageType.TYPE_REG_CLT_RESULT:
+                msgCodec = new RegisterTMResponseCodec();
+                break;
+            case MessageType.TYPE_REG_RM:
+                msgCodec = new RegisterRMRequestCodec();
+                break;
+            case MessageType.TYPE_REG_RM_RESULT:
+                msgCodec = new RegisterRMResponseCodec();
+                break;
+            case MessageType.TYPE_BRANCH_COMMIT:
+                msgCodec = new BranchCommitRequestCodec();
+                break;
+            case MessageType.TYPE_BRANCH_ROLLBACK:
+                msgCodec = new BranchRollbackRequestCodec();
+                break;
+            default:
+                break;
+        }
+
+        if (null != msgCodec) {
+            return msgCodec;
+        }
+
+        try {
+            msgCodec = getMergeRequestMessageSeataCodec(typeCode);
+        } catch (Exception exx) {}
+
+        if (null != msgCodec) {
+            return msgCodec;
+        }
+
+        msgCodec = getMergeResponseMessageSeataCodec(typeCode);
+
+        return msgCodec;
+    }
+
+    /**
+     * Gets merge request instance by code.
+     *
+     * @param typeCode the type code
+     * @return the merge request instance by code
+     */
+    protected static MessageSeataCodec getMergeRequestMessageSeataCodec(int typeCode) {
+        switch (typeCode) {
+            case MessageType.TYPE_GLOBAL_BEGIN:
+                return new GlobalBeginRequestCodec();
+            case MessageType.TYPE_GLOBAL_COMMIT:
+                return new GlobalCommitRequestCodec();
+            case MessageType.TYPE_GLOBAL_ROLLBACK:
+                return new GlobalRollbackRequestCodec();
+            case MessageType.TYPE_GLOBAL_STATUS:
+                return new GlobalStatusRequestCodec();
+            case MessageType.TYPE_GLOBAL_LOCK_QUERY:
+                return new GlobalLockQueryRequestCodec();
+            case MessageType.TYPE_BRANCH_REGISTER:
+                return new BranchRegisterRequestCodec();
+            case MessageType.TYPE_BRANCH_STATUS_REPORT:
+                return new BranchReportRequestCodec();
+            default:
+                throw new IllegalArgumentException("not support typeCode," + typeCode);
+        }
+    }
+
+    /**
+     * Gets merge response instance by code.
+     *
+     * @param typeCode the type code
+     * @return the merge response instance by code
+     */
+    protected static MessageSeataCodec getMergeResponseMessageSeataCodec(int typeCode) {
+        switch (typeCode) {
+            case MessageType.TYPE_GLOBAL_BEGIN_RESULT:
+                return new GlobalBeginResponseCodec();
+            case MessageType.TYPE_GLOBAL_COMMIT_RESULT:
+                return new GlobalCommitResponseCodec();
+            case MessageType.TYPE_GLOBAL_ROLLBACK_RESULT:
+                return new GlobalRollbackResponseCodec();
+            case MessageType.TYPE_GLOBAL_STATUS_RESULT:
+                return new GlobalStatusResponseCodec();
+            case MessageType.TYPE_GLOBAL_LOCK_QUERY_RESULT:
+                return new GlobalLockQueryResponseCodec();
+            case MessageType.TYPE_BRANCH_REGISTER_RESULT:
+                return new BranchRegisterResponseCodec();
+            case MessageType.TYPE_BRANCH_STATUS_REPORT_RESULT:
+                return new BranchReportResponseCodec();
+            case MessageType.TYPE_BRANCH_COMMIT_RESULT:
+                return new BranchCommitResponseCodec();
+            case MessageType.TYPE_BRANCH_ROLLBACK_RESULT:
+                return new BranchRollbackResponseCodec();
+            default:
+                throw new IllegalArgumentException("not support typeCode," + typeCode);
+        }
+    }
+
+
+    /**
+     * Gets message.
+     *
+     * @param typeCode the type code
+     * @return the message
+     */
+    public static AbstractMessage getMessage(short typeCode) {
+        AbstractMessage abstractMessage = null;
+        switch (typeCode) {
+            case MessageType.TYPE_SEATA_MERGE:
+                abstractMessage = new MergedWarpMessage();
+                break;
+            case MessageType.TYPE_SEATA_MERGE_RESULT:
+                abstractMessage = new MergeResultMessage();
+                break;
+            case MessageType.TYPE_REG_CLT:
+                abstractMessage = new RegisterTMRequest();
+                break;
+            case MessageType.TYPE_REG_CLT_RESULT:
+                abstractMessage = new RegisterTMResponse();
+                break;
+            case MessageType.TYPE_REG_RM:
+                abstractMessage = new RegisterRMRequest();
+                break;
+            case MessageType.TYPE_REG_RM_RESULT:
+                abstractMessage = new RegisterRMResponse();
+                break;
+            case MessageType.TYPE_BRANCH_COMMIT:
+                abstractMessage = new BranchCommitRequest();
+                break;
+            case MessageType.TYPE_BRANCH_ROLLBACK:
+                abstractMessage = new BranchRollbackRequest();
+                break;
+            default:
+                break;
+        }
+
+        if (null != abstractMessage) {
+            return abstractMessage;
+        }
+
+        try {
+            abstractMessage = getMergeRequestInstanceByCode(typeCode);
+        } catch (Exception exx) {}
+
+        if (null != abstractMessage) {
+            return abstractMessage;
+        }
+
+        return getMergeResponseInstanceByCode(typeCode);
+    }
+
+
+    /**
+     * Gets merge request instance by code.
+     *
+     * @param typeCode the type code
+     * @return the merge request instance by code
+     */
+    protected static AbstractMessage getMergeRequestInstanceByCode(int typeCode) {
+        switch (typeCode) {
+            case MessageType.TYPE_GLOBAL_BEGIN:
+                return new GlobalBeginRequest();
+            case MessageType.TYPE_GLOBAL_COMMIT:
+                return new GlobalCommitRequest();
+            case MessageType.TYPE_GLOBAL_ROLLBACK:
+                return new GlobalRollbackRequest();
+            case MessageType.TYPE_GLOBAL_STATUS:
+                return new GlobalStatusRequest();
+            case MessageType.TYPE_GLOBAL_LOCK_QUERY:
+                return new GlobalLockQueryRequest();
+            case MessageType.TYPE_BRANCH_REGISTER:
+                return new BranchRegisterRequest();
+            case MessageType.TYPE_BRANCH_STATUS_REPORT:
+                return new BranchReportRequest();
+            default:
+                throw new IllegalArgumentException("not support typeCode," + typeCode);
+        }
+    }
+
+    /**
+     * Gets merge response instance by code.
+     *
+     * @param typeCode the type code
+     * @return the merge response instance by code
+     */
+    protected static AbstractMessage getMergeResponseInstanceByCode(int typeCode) {
+        switch (typeCode) {
+            case MessageType.TYPE_GLOBAL_BEGIN_RESULT:
+                return new GlobalBeginResponse();
+            case MessageType.TYPE_GLOBAL_COMMIT_RESULT:
+                return new GlobalCommitResponse();
+            case MessageType.TYPE_GLOBAL_ROLLBACK_RESULT:
+                return new GlobalRollbackResponse();
+            case MessageType.TYPE_GLOBAL_STATUS_RESULT:
+                return new GlobalStatusResponse();
+            case MessageType.TYPE_GLOBAL_LOCK_QUERY_RESULT:
+                return new GlobalLockQueryResponse();
+            case MessageType.TYPE_BRANCH_REGISTER_RESULT:
+                return new BranchRegisterResponse();
+            case MessageType.TYPE_BRANCH_STATUS_REPORT_RESULT:
+                return new BranchReportResponse();
+            case MessageType.TYPE_BRANCH_COMMIT_RESULT:
+                return new BranchCommitResponse();
+            case MessageType.TYPE_BRANCH_ROLLBACK_RESULT:
+                return new BranchRollbackResponse();
+            default:
+                throw new IllegalArgumentException("not support typeCode," + typeCode);
+        }
+    }
+
+
+    /**
+     * Get byte buffer byte buffer.
+     *
+     * @param abstractMessage the abstract message
+     * @return the byte buffer
+     */
+    public static ByteBuffer getByteBuffer(AbstractMessage abstractMessage ){
+        int bufferSize = 1024;
+        if(abstractMessage instanceof MergedWarpMessage){
+            bufferSize = ((MergedWarpMessage)abstractMessage).msgs.size() * 1024 + 4;
+        }else if(abstractMessage instanceof MergeResultMessage){
+            bufferSize = ((MergeResultMessage)abstractMessage).msgs.length * 1024 + 4;
+        }else if(abstractMessage instanceof AbstractIdentifyRequest){
+            bufferSize = 10 * 1024;
+        }else if (abstractMessage instanceof AbstractResultMessage){
+            bufferSize = 512;
+        }else if(abstractMessage instanceof AbstractBranchEndRequest){
+            AbstractBranchEndRequest abstractBranchEndRequest = (AbstractBranchEndRequest) abstractMessage;
+            byte[] applicationDataBytes = null;
+            if (abstractBranchEndRequest.getApplicationData() != null) {
+                applicationDataBytes = abstractBranchEndRequest.getApplicationData().getBytes(UTF8);
+                if (applicationDataBytes.length > 512) {
+                    bufferSize = applicationDataBytes.length + 1024;
+                }else {
+                    bufferSize = 1024;
+                }
+            }else {
+                bufferSize = 1024;
+            }
+        }else if(abstractMessage instanceof GlobalBeginRequest){
+            bufferSize = 256;
+        }else if(abstractMessage instanceof AbstractGlobalEndRequest){
+            bufferSize = 256;
+        }else if(abstractMessage instanceof BranchRegisterRequest){
+            BranchRegisterRequest branchRegisterRequest = (BranchRegisterRequest) abstractMessage;
+            int byteLenth = 0;
+            byte[] lockKeyBytes = null;
+            if (branchRegisterRequest.getLockKey() != null) {
+                lockKeyBytes = branchRegisterRequest.getLockKey().getBytes(UTF8);
+                if (lockKeyBytes.length > 512) {
+                    byteLenth += lockKeyBytes.length;
+                }
+            }
+            byte[] applicationDataBytes = null;
+            if (branchRegisterRequest.getApplicationData() != null) {
+                applicationDataBytes = branchRegisterRequest.getApplicationData().getBytes(UTF8);
+                if (applicationDataBytes.length > 512) {
+                    byteLenth += applicationDataBytes.length;
+                }
+            }
+            bufferSize = byteLenth + 1024;
+        }else if(abstractMessage instanceof BranchReportRequest){
+            BranchReportRequest branchReportRequest = (BranchReportRequest) abstractMessage;
+            int byteLenth = 0;
+            byte[] applicationDataBytes = null;
+            if (branchReportRequest.getApplicationData() != null) {
+                applicationDataBytes = branchReportRequest.getApplicationData().getBytes(UTF8);
+                if (applicationDataBytes.length > 512) {
+                    byteLenth += (applicationDataBytes.length);
+                }
+            }
+            bufferSize = byteLenth + 1024;
+        }else {
+            bufferSize = 512;
+        }
+        return ByteBuffer.allocate(bufferSize);
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageSeataCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageSeataCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..4df547b81c2eb9b7bc3f84047de3e0051504e1ea
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/MessageSeataCodec.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata;
+
+
+import java.nio.ByteBuffer;
+
+/**
+ * The interface Message seata codec.
+ *
+ * @author zhangsen
+ */
+public interface MessageSeataCodec {
+
+    /**
+     * Gets message type.
+     *
+     * @return the message type
+     */
+    public Class<?> getMessageClassType();
+
+    /**
+     * Encode byte [ ].
+     *
+     * @param <T> the type parameter
+     * @param t   the t
+     * @param out the out
+     * @return the byte [ ]
+     */
+    <T> void encode(T t, ByteBuffer out);
+
+    /**
+     * Decode.
+     *
+     * @param <T> the type parameter
+     * @param t   the t
+     * @param in  the in
+     */
+    <T> void decode(T t, ByteBuffer in);
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/SeataCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/SeataCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..c65d344c5ab42e3d8621b29fb5fbd6a4ab3fcc57
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/SeataCodec.java
@@ -0,0 +1,87 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata;
+
+import io.seata.common.loader.LoadLevel;
+import io.seata.core.codec.Codec;
+import io.seata.core.protocol.AbstractMessage;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The Seata codec.
+ *
+ * @author zhangsen
+ * @data 2019 /5/6
+ */
+@LoadLevel(name="SEATA")
+public class SeataCodec implements Codec {
+
+    @Override
+    public <T> byte[] encode(T t) {
+        if(t == null || !(t instanceof AbstractMessage)){
+            throw new IllegalArgumentException("AbstractMessage isn't available.");
+        }
+        AbstractMessage abstractMessage = (AbstractMessage) t;
+        //typecode
+        short typecode = abstractMessage.getTypeCode();
+        //msg codec
+        MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typecode);
+        //get empty ByteBuffer
+        ByteBuffer out = MessageCodecFactory.getByteBuffer(abstractMessage);
+        //msg encode
+        messageCodec.encode(t, out);
+        out.flip();
+        byte[] body = new byte[out.limit()];
+        out.get(body);
+
+        //typecode + body
+        ByteBuffer byteBuffer = ByteBuffer.allocate(4+ body.length);
+        byteBuffer.putShort(typecode);
+        byteBuffer.put(body);
+
+        byteBuffer.flip();
+        byte[] content = new byte[byteBuffer.limit()];
+        byteBuffer.get(content);
+        return content;
+    }
+
+    @Override
+    public <T> T decode(byte[] bytes) {
+        if(bytes == null || bytes.length == 0){
+            throw new IllegalArgumentException("Nothing to decode.");
+        }
+        if(bytes.length < 2){
+            throw new IllegalArgumentException("The byte[] isn't available for decode.");
+        }
+        ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+        //typecode
+        short typecode = byteBuffer.getShort();
+        //msg body
+        byte[] body = new byte[byteBuffer.remaining()];
+        byteBuffer.get(body);
+        ByteBuffer in = ByteBuffer.wrap(body);
+        //new Messgae
+        AbstractMessage abstractMessage = MessageCodecFactory.getMessage(typecode);
+        //get messageCodec
+        MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typecode);
+        //decode
+        messageCodec.decode(abstractMessage, in);
+        return (T) abstractMessage;
+    }
+
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..40b4482dab8db3958500804a68a078922af4e3e0
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyRequestCodec.java
@@ -0,0 +1,154 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+
+import io.seata.core.protocol.AbstractIdentifyRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract identify request codec.
+ */
+public abstract class AbstractIdentifyRequestCodec extends AbstractMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType(){
+        return AbstractIdentifyRequest.class;
+    }
+
+    /**
+     * Do encode.
+     *
+     * @param <T> the type parameter
+     * @param t   the t
+     * @param out the out
+     */
+    protected <T> void doEncode(T t, ByteBuffer out) {
+        AbstractIdentifyRequest abstractIdentifyRequest = (AbstractIdentifyRequest) t;
+        String version = abstractIdentifyRequest.getVersion();
+        String applicationId = abstractIdentifyRequest.getApplicationId();
+        String transactionServiceGroup = abstractIdentifyRequest.getTransactionServiceGroup();
+        String extraData = abstractIdentifyRequest.getExtraData();
+
+        if (version != null) {
+            byte[] bs = version.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        if (applicationId != null) {
+            byte[] bs = applicationId.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        if (transactionServiceGroup != null) {
+            byte[] bs = transactionServiceGroup.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        if (extraData != null) {
+            byte[] bs = extraData.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        doEncode(t, out);
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in){
+        AbstractIdentifyRequest abstractIdentifyRequest = (AbstractIdentifyRequest) t;
+
+        //version len
+        short len = 0;
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+        //version
+        if (in.remaining() < len) {
+            return ;
+        }
+        byte[] bs = new byte[len];
+        in.get(bs);
+        abstractIdentifyRequest.setVersion(new String(bs, UTF8));
+
+        //applicationId len
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+        //applicationId
+        if (in.remaining() < len) {
+            return ;
+        }
+        bs = new byte[len];
+        in.get(bs);
+        abstractIdentifyRequest.setApplicationId(new String(bs, UTF8));
+
+        //transactionServiceGroup len
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+
+        //transactionServiceGroup
+        if (in.remaining() < len) {
+            return ;
+        }
+        bs = new byte[len];
+        in.get(bs);
+        abstractIdentifyRequest.setTransactionServiceGroup(new String(bs, UTF8));
+
+        //ExtraData len
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+
+        if (in.remaining() >= len) {
+            bs = new byte[len];
+            in.get(bs);
+            abstractIdentifyRequest.setExtraData(new String(bs, UTF8));
+        } else {
+            //maybe null
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..fd84ab57a26376eda732b21335a8dbb15c906b7e
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractIdentifyResponseCodec.java
@@ -0,0 +1,69 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.core.protocol.AbstractIdentifyResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract identify response.
+ *
+ * @author sharajava
+ */
+public abstract class AbstractIdentifyResponseCodec extends AbstractResultMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractIdentifyResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        AbstractIdentifyResponse abstractIdentifyResponse = (AbstractIdentifyResponse) t;
+        boolean identified = abstractIdentifyResponse.isIdentified();
+        String version = abstractIdentifyResponse.getVersion();
+
+        out.put(identified ? (byte)1 : (byte)0);
+        if (version != null) {
+            byte[] bs = version.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in){
+        AbstractIdentifyResponse abstractIdentifyResponse = (AbstractIdentifyResponse) t;
+
+        abstractIdentifyResponse.setIdentified(in.get() == 1);
+        short len = in.getShort();
+        if (len <= 0) {
+            return ;
+        }
+        if (in.remaining() < len) {
+            return ;
+        }
+        byte[] bs = new byte[len];
+        in.get(bs);
+        abstractIdentifyResponse.setVersion(new String(bs, UTF8));
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractMessageCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractMessageCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a6a9f19e8b5b84584960da9f5c2d07d533d3e7c
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractMessageCodec.java
@@ -0,0 +1,71 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.MessageSeataCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.nio.charset.Charset;
+
+/**
+ * The type Abstract message codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractMessageCodec implements MessageSeataCodec {
+
+    /**
+     * The constant LOGGER.
+     */
+    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractMessageCodec.class);
+
+    /**
+     * The constant UTF8.
+     */
+    protected static final Charset UTF8 = Charset.forName("utf-8");
+
+    /**
+     * Bytes to int int.
+     *
+     * @param bytes  the bytes
+     * @param offset the offset
+     * @return the int
+     */
+    public static int bytesToInt(byte[] bytes, int offset) {
+        int ret = 0;
+        for (int i = 0; i < 4 && i + offset < bytes.length; i++) {
+            ret <<= 8;
+            ret |= (int)bytes[i + offset] & 0xFF;
+        }
+        return ret;
+    }
+
+    /**
+     * Int to bytes.
+     *
+     * @param i      the
+     * @param bytes  the bytes
+     * @param offset the offset
+     */
+    public static void intToBytes(int i, byte[] bytes, int offset) {
+        bytes[offset] = (byte)((i >> 24) & 0xFF);
+        bytes[offset + 1] = (byte)((i >> 16) & 0xFF);
+        bytes[offset + 2] = (byte)((i >> 8) & 0xFF);
+        bytes[offset + 3] = (byte)(i & 0xFF);
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractResultMessageCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractResultMessageCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..a763567aef0ebab96f09446ea8abea6b9564251b
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/AbstractResultMessageCodec.java
@@ -0,0 +1,82 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.core.protocol.AbstractIdentifyResponse;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.ResultCode;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract result message codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractResultMessageCodec extends AbstractMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractResultMessage.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        AbstractResultMessage abstractResultMessage = (AbstractResultMessage) t;
+        ResultCode resultCode = abstractResultMessage.getResultCode();
+        String resultMsg = abstractResultMessage.getMsg();
+
+        out.put((byte)resultCode.ordinal());
+        if (resultCode == ResultCode.Failed) {
+            if (resultMsg != null) {
+                String msg;
+                if (resultMsg.length() > 128) {
+                    msg = resultMsg.substring(0, 128);
+                } else {
+                    msg = resultMsg;
+                }
+                byte[] bs = msg.getBytes(UTF8);
+                if (bs.length > 400 && resultMsg.length() > 64) {
+                    msg = resultMsg.substring(0, 64);
+                    bs = msg.getBytes(UTF8);
+                }
+                out.putShort((short)bs.length);
+                if (bs.length > 0) {
+                    out.put(bs);
+                }
+            } else {
+                out.putShort((short)0);
+            }
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in){
+        AbstractResultMessage abstractResultMessage = (AbstractResultMessage) t;
+
+        ResultCode resultCode= ResultCode.get(in.get());
+        abstractResultMessage.setResultCode(resultCode);
+        if (resultCode == ResultCode.Failed) {
+            short len = in.getShort();
+            if (len > 0) {
+                byte[] msg = new byte[len];
+                in.get(msg);
+                abstractResultMessage.setMsg(new String(msg, UTF8));
+            }
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergeResultMessageCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergeResultMessageCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..83c34325b856cb374fd353b1fac418f0ed1711fa
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergeResultMessageCodec.java
@@ -0,0 +1,104 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.MessageCodecFactory;
+import io.seata.codec.seata.MessageSeataCodec;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.MergeResultMessage;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Merge result message codec.
+ *
+ * @author zhangsen
+ */
+public class MergeResultMessageCodec extends AbstractMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return MergeResultMessage.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        MergeResultMessage mergeResultMessage = (MergeResultMessage) t;
+        AbstractResultMessage[] msgs = mergeResultMessage.getMsgs();
+
+        ByteBuffer byteBuffer = ByteBuffer.allocate(msgs.length * 1024);
+        byteBuffer.putShort((short)msgs.length);
+        for (AbstractMessage msg : msgs) {
+            //get messageCodec
+            short typeCode = msg.getTypeCode();
+            //put typeCode
+            byteBuffer.putShort(typeCode);
+            MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typeCode);
+            messageCodec.encode(msg, byteBuffer);
+        }
+
+        byteBuffer.flip();
+        int length = byteBuffer.limit();
+        byte[] content = new byte[length + 4];
+        intToBytes(length, content, 0);
+        byteBuffer.get(content, 4, length);
+        if (msgs.length > 20) {
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("msg in one services merge packet:" + msgs.length  + ",buffer size:" + content.length);
+            }
+        }
+        out.put(content);
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        MergeResultMessage mergeResultMessage = (MergeResultMessage) t;
+
+        if (in.remaining() < 4) {
+            return ;
+        }
+        int length = in.getInt();
+        if (in.remaining() < length) {
+            return ;
+        }
+        byte[] buffer = new byte[length];
+        in.get(buffer);
+        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
+        decode(mergeResultMessage, byteBuffer);
+    }
+
+    /**
+     * Decode.
+     *
+     * @param mergeResultMessage the merge result message
+     * @param byteBuffer         the byte buffer
+     */
+    protected void decode(MergeResultMessage mergeResultMessage, ByteBuffer byteBuffer) {
+        //msgs size
+        short msgNum = byteBuffer.getShort();
+        AbstractResultMessage[] msgs = new AbstractResultMessage[msgNum];
+        for (int idx = 0; idx < msgNum; idx++) {
+            short typeCode = byteBuffer.getShort();
+            AbstractMessage abstractResultMessage = MessageCodecFactory.getMessage(typeCode);
+            MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typeCode);
+            messageCodec.decode(abstractResultMessage, byteBuffer);
+            msgs[idx] = (AbstractResultMessage)abstractResultMessage;
+        }
+        mergeResultMessage.setMsgs(msgs);
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergedWarpMessageCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergedWarpMessageCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..4837feac6d0399e69736c5fc65897c2599f7413b
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/MergedWarpMessageCodec.java
@@ -0,0 +1,104 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.seata.codec.seata.MessageCodecFactory;
+import io.seata.codec.seata.MessageSeataCodec;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The type Merged warp message codec.
+ *
+ * @author zhangsen
+ */
+public class MergedWarpMessageCodec extends AbstractMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return MergedWarpMessage.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        MergedWarpMessage mergedWarpMessage = (MergedWarpMessage) t;
+        List<AbstractMessage> msgs = mergedWarpMessage.msgs;
+
+        final ByteBuf buffer = Unpooled.buffer(1024);
+        buffer.writeInt(0); // write placeholder for content length
+
+        buffer.writeShort((short) msgs.size());
+        for (final AbstractMessage msg : msgs) {
+            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
+            short typeCode = msg.getTypeCode();
+            MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typeCode);
+            messageCodec.encode(msg, byteBuffer);
+            byteBuffer.flip();
+            buffer.writeShort(msg.getTypeCode());
+            buffer.writeBytes(byteBuffer);
+        }
+
+        final int length = buffer.readableBytes();
+        final byte[] content = new byte[length];
+        buffer.setInt(0, length - 4);  // minus the placeholder length itself
+        buffer.readBytes(content);
+
+        if (msgs.size() > 20) {
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("msg in one packet:" + msgs.size() + ",buffer size:" + content.length);
+            }
+        }
+        out.put(content);
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        MergedWarpMessage mergedWarpMessage = (MergedWarpMessage) t;
+
+        if (in.remaining() < 4) {
+            return ;
+        }
+        int length = in.getInt();
+        if (in.remaining() < length) {
+            return ;
+        }
+        byte[] buffer = new byte[length];
+        in.get(buffer);
+        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
+        doDecode(mergedWarpMessage, byteBuffer);
+    }
+
+    private void doDecode(MergedWarpMessage mergedWarpMessage, ByteBuffer byteBuffer) {
+        short msgNum = byteBuffer.getShort();
+        List<AbstractMessage> msgs = new ArrayList<AbstractMessage>();
+        for (int idx = 0; idx < msgNum; idx++) {
+            short typeCode = byteBuffer.getShort();
+            AbstractMessage abstractMessage = MessageCodecFactory.getMessage(typeCode);
+            MessageSeataCodec messageCodec = MessageCodecFactory.getMessageCodec(typeCode);
+            messageCodec.decode(abstractMessage, byteBuffer);
+            msgs.add(abstractMessage);
+        }
+        mergedWarpMessage.msgs = msgs;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..087fed940e5d4665ff7d8df8def25f7027b11365
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMRequestCodec.java
@@ -0,0 +1,127 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.RegisterRMRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Register rm request codec.
+ *
+ * @author zhangsen
+ */
+public class RegisterRMRequestCodec extends AbstractIdentifyRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return RegisterRMRequest.class;
+    }
+
+    @Override
+    protected <T> void doEncode(T t, ByteBuffer out) {
+        super.doEncode(t, out);
+
+        RegisterRMRequest registerRMRequest = (RegisterRMRequest) t;
+        String resourceIds = registerRMRequest.getResourceIds();
+
+        if (resourceIds != null) {
+            byte[] bs = resourceIds.getBytes(UTF8);
+            out.putInt(bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putInt(0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        RegisterRMRequest registerRMRequest = (RegisterRMRequest) t;
+
+        if (in.remaining() < 2) {
+            return ;
+        }
+        short len = in.getShort();
+        if (len > 0) {
+            if (in.remaining() < len) {
+                return ;
+            }
+            byte[] bs = new byte[len];
+            in.get(bs);
+            registerRMRequest.setVersion(new String(bs, UTF8));
+        } else {
+            return ;
+        }
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+
+        if (len > 0) {
+            if (in.remaining() < len) {
+                return ;
+            }
+            byte[] bs = new byte[len];
+            in.get(bs);
+            registerRMRequest.setApplicationId(new String(bs, UTF8));
+        }
+
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+
+        if (in.remaining() < len) {
+            return ;
+        }
+        byte[] bs = new byte[len];
+        in.get(bs);
+        registerRMRequest.setTransactionServiceGroup(new String(bs, UTF8));
+
+        if (in.remaining() < 2) {
+            return ;
+        }
+        len = in.getShort();
+
+        if (len > 0) {
+            if (in.remaining() < len) {
+                return ;
+            }
+            bs = new byte[len];
+            in.get(bs);
+            registerRMRequest.setExtraData(new String(bs, UTF8));
+        }
+
+        int iLen;
+        if (in.remaining() < 4) {
+            return ;
+        }
+        iLen = in.getInt();
+
+        if (iLen > 0) {
+            if (in.remaining() < iLen) {
+                return ;
+            }
+            bs = new byte[iLen];
+            in.get(bs);
+            registerRMRequest.setResourceIds(new String(bs, UTF8));
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef8b4868149589d28449e72de6ebb95a4da9f07e
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterRMResponseCodec.java
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.core.protocol.RegisterRMResponse;
+
+/**
+ * The type Register rm response codec.
+ *
+ * @author zhangsen
+ */
+public class RegisterRMResponseCodec extends AbstractIdentifyResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return RegisterRMResponse.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c18be67b5ad5afd5322077f60f0a912d9983af4
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMRequestCodec.java
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+
+import io.seata.core.protocol.RegisterTMRequest;
+
+/**
+ * The type Register tm request codec.
+ *
+ * @author zhangsen
+ */
+public class RegisterTMRequestCodec extends AbstractIdentifyRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return RegisterTMRequest.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..112b7245287a60c344ef37279e510f72aaed03bd
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/RegisterTMResponseCodec.java
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+
+import io.seata.core.protocol.RegisterTMResponse;
+
+/**
+ * The type Register tm response codec.
+ *
+ * @author zhangsen
+ */
+public class RegisterTMResponseCodec extends AbstractIdentifyResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return RegisterTMResponse.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cef1c59c0c1b4c38ae1740769777a6e11b3b2f3
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndRequestCodec.java
@@ -0,0 +1,143 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.AbstractBranchEndRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract branch end request codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractBranchEndRequestCodec extends AbstractTransactionRequestToRMCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractBranchEndRequest.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out){
+        AbstractBranchEndRequest abstractBranchEndRequest = (AbstractBranchEndRequest) t;
+        String  xid = abstractBranchEndRequest.getXid();
+        long branchId =  abstractBranchEndRequest.getBranchId();
+        BranchType branchType = abstractBranchEndRequest.getBranchType();
+        String resourceId = abstractBranchEndRequest.getResourceId();
+        String applicationData = abstractBranchEndRequest.getApplicationData();
+
+        // 1. xid
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+        // 2. Branch Id
+        out.putLong(branchId);
+        // 3. Branch Type
+        out.put((byte)branchType.ordinal());
+        // 4. Resource Id
+        if (resourceId != null) {
+            byte[] bs = resourceId.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        // 5. Application Data
+        byte[] applicationDataBytes = null;
+        if (applicationData != null) {
+            applicationDataBytes = applicationData.getBytes(UTF8);
+            out.putInt(applicationDataBytes.length);
+            if (applicationDataBytes.length > 0) {
+                out.put(applicationDataBytes);
+            }
+        } else {
+            out.putInt(0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        AbstractBranchEndRequest abstractBranchEndRequest = (AbstractBranchEndRequest) t;
+
+        int xidLen = 0;
+        if (in.remaining() >= 2) {
+            xidLen = in.getShort();
+        }
+        if (xidLen <= 0) {
+            return ;
+        }
+        if (in.remaining() < xidLen) {
+            return ;
+        }
+        byte[] bs = new byte[xidLen];
+        in.get(bs);
+        abstractBranchEndRequest.setXid(new String(bs, UTF8));
+
+        if (in.remaining() < 8) {
+            return ;
+        }
+        abstractBranchEndRequest.setBranchId(in.getLong());
+
+        if (in.remaining() < 1) {
+            return ;
+        }
+        abstractBranchEndRequest.setBranchType(BranchType.get(in.get()));
+
+        int resourceIdLen = 0;
+        if (in.remaining() < 2) {
+            return ;
+        }
+        resourceIdLen = in.getShort();
+
+        if (resourceIdLen <= 0) {
+            return ;
+        }
+        if (in.remaining() < resourceIdLen) {
+            return ;
+        }
+        bs = new byte[resourceIdLen];
+        in.get(bs);
+        abstractBranchEndRequest.setResourceId(new String(bs, UTF8));
+
+        int applicationDataLen = 0;
+        if (in.remaining() < 4) {
+            return ;
+        }
+        applicationDataLen = in.getInt();
+
+        if (applicationDataLen > 0) {
+            if (in.remaining() < applicationDataLen) {
+                return ;
+            }
+            bs = new byte[applicationDataLen];
+            in.get(bs);
+            abstractBranchEndRequest.setApplicationData(new String(bs, UTF8));
+        }
+    }
+
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6a2ee3a69655196fdc20147db2c9fae83e247b5
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractBranchEndResponseCodec.java
@@ -0,0 +1,76 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.netty.buffer.ByteBuf;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.transaction.AbstractBranchEndRequest;
+import io.seata.core.protocol.transaction.AbstractBranchEndResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract branch end response codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractBranchEndResponseCodec extends AbstractTransactionResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractBranchEndResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        super.encode(t, out);
+
+        AbstractBranchEndResponse abstractBranchEndResponse = (AbstractBranchEndResponse) t;
+        String xid = abstractBranchEndResponse.getXid();
+        long branchId = abstractBranchEndResponse.getBranchId();
+        BranchStatus branchStatus = abstractBranchEndResponse.getBranchStatus();
+
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+        out.putLong(branchId);
+        out.put((byte)branchStatus.getCode());
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        super.decode(t, in);
+
+        AbstractBranchEndResponse abstractBranchEndResponse = (AbstractBranchEndResponse) t;
+        short xidLen = in.getShort();
+        if (xidLen > 0) {
+            byte[] bs = new byte[xidLen];
+            in.get(bs);
+            abstractBranchEndResponse.setXid(new String(bs, UTF8));
+        }
+        abstractBranchEndResponse.setBranchId(in.getLong());
+        abstractBranchEndResponse.setBranchStatus(BranchStatus.get(in.get()));
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3e8bc99af71be3bcee54931262d8078aadb8b20
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndRequestCodec.java
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.AbstractGlobalEndRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract global end request codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractGlobalEndRequestCodec extends AbstractTransactionRequestToTCCodec  {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractGlobalEndRequest.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        AbstractGlobalEndRequest abstractGlobalEndRequest = (AbstractGlobalEndRequest) t;
+        String xid = abstractGlobalEndRequest.getXid();
+        String extraData = abstractGlobalEndRequest.getExtraData();
+
+        // 1. xid
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+        if (extraData != null) {
+            byte[] bs = extraData.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        AbstractGlobalEndRequest abstractGlobalEndRequest = (AbstractGlobalEndRequest) t;
+
+        short xidLen = in.getShort();
+        if (xidLen > 0) {
+            byte[] bs = new byte[xidLen];
+            in.get(bs);
+            abstractGlobalEndRequest.setXid(new String(bs, UTF8));
+        }
+        short len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            abstractGlobalEndRequest.setExtraData(new String(bs, UTF8));
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..aac3f5e076c94165eabdf1dbe0178b9a910071ef
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractGlobalEndResponseCodec.java
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.transaction.AbstractGlobalEndRequest;
+import io.seata.core.protocol.transaction.AbstractGlobalEndResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract global end response codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractGlobalEndResponseCodec extends AbstractTransactionResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractGlobalEndResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer in) {
+        super.encode(t, in);
+
+        AbstractGlobalEndResponse abstractGlobalEndResponse = (AbstractGlobalEndResponse) t;
+        GlobalStatus globalStatus = abstractGlobalEndResponse.getGlobalStatus();
+        in.put((byte)globalStatus.getCode());
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        super.decode(t, in);
+
+        AbstractGlobalEndResponse abstractGlobalEndResponse = (AbstractGlobalEndResponse) t;
+
+        abstractGlobalEndResponse.setGlobalStatus(GlobalStatus.get(in.get()));
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6277a851fb3e1bfad730429a494c843cb219026
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestCodec.java
@@ -0,0 +1,37 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.protocol.AbstractMessageCodec;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.transaction.AbstractBranchEndRequest;
+import io.seata.core.protocol.transaction.AbstractTransactionRequest;
+import io.seata.core.rpc.RpcContext;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract transaction request codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractTransactionRequestCodec extends AbstractMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractTransactionRequest.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToRMCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToRMCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..1413b476c49df2baee73512c0446ad9c299ccb78
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToRMCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.AbstractTransactionRequestToRM;
+
+/**
+ * The type Abstract transaction request to rm codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractTransactionRequestToRMCodec extends AbstractTransactionRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractTransactionRequestToRM.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToTCCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToTCCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..c66b2c52e49c0af72250f62d675780014f3285fb
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionRequestToTCCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.AbstractTransactionRequestToTC;
+
+/**
+ * The type Abstract transaction request to tc codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractTransactionRequestToTCCodec extends AbstractTransactionRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractTransactionRequestToTC.class;
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f7913d6e03890c220be67e8896682767ac66265
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/AbstractTransactionResponseCodec.java
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.codec.seata.protocol.AbstractResultMessageCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.transaction.AbstractTransactionResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Abstract transaction response codec.
+ *
+ * @author zhangsen
+ */
+public abstract class AbstractTransactionResponseCodec extends AbstractResultMessageCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return AbstractTransactionResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        super.encode(t, out);
+
+        AbstractTransactionResponse abstractTransactionResponse = (AbstractTransactionResponse) t;
+        TransactionExceptionCode transactionExceptionCode = abstractTransactionResponse.getTransactionExceptionCode();
+        out.put((byte)transactionExceptionCode.ordinal());
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer out) {
+        super.decode(t, out);
+
+        AbstractTransactionResponse abstractTransactionResponse = (AbstractTransactionResponse) t;
+        abstractTransactionResponse.setTransactionExceptionCode(TransactionExceptionCode.get(out.get()));
+    }
+
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..47dcd04c8c23f3de2d9b2005dc777570036eb670
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+
+/**
+ * The type Branch commit request codec.
+ *
+ * @author zhangsen
+ */
+public class BranchCommitRequestCodec extends AbstractBranchEndRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchCommitRequest.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d61422b9e12a4b84d8dd79cf689aab065e71f6f
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+
+/**
+ * The type Branch commit response codec.
+ *
+ * @author zhangsen
+ */
+public class BranchCommitResponseCodec extends AbstractBranchEndResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchCommitResponse.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..834ca2bb6457df062dcf175efb68f9e7507e0de4
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodec.java
@@ -0,0 +1,132 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Branch register request codec.
+ *
+ * @author zhangsen
+ */
+public class BranchRegisterRequestCodec extends AbstractTransactionRequestToTCCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchRegisterRequest.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        BranchRegisterRequest branchRegisterRequest = (BranchRegisterRequest) t;
+
+        String xid = branchRegisterRequest.getXid();
+        BranchType branchType = branchRegisterRequest.getBranchType();
+        String resourceId = branchRegisterRequest.getResourceId();
+        String lockKey = branchRegisterRequest.getLockKey();
+        String applicationData = branchRegisterRequest.getApplicationData();
+
+        byte[] lockKeyBytes = null;
+        if (lockKey != null) {
+            lockKeyBytes = lockKey.getBytes(UTF8);
+        }
+        byte[] applicationDataBytes = null;
+        if (applicationData != null) {
+            applicationDataBytes = applicationData.getBytes(UTF8);
+        }
+
+        // 1. xid
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+        // 2. Branch Type
+        out.put((byte)branchType.ordinal());
+
+        // 3. Resource Id
+        if (resourceId != null) {
+            byte[] bs = resourceId.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        // 4. Lock Key
+        if (lockKey != null) {
+            out.putInt(lockKeyBytes.length);
+            if (lockKeyBytes.length > 0) {
+                out.put(lockKeyBytes);
+            }
+        } else {
+            out.putInt(0);
+        }
+
+        //5. applicationData
+        if (applicationData != null) {
+            out.putInt(applicationDataBytes.length);
+            if (applicationDataBytes.length > 0) {
+                out.put(applicationDataBytes);
+            }
+        } else {
+            out.putInt(0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        BranchRegisterRequest branchRegisterRequest = (BranchRegisterRequest) t;
+
+        short xidLen = in.getShort();
+        if (xidLen > 0) {
+            byte[] bs = new byte[xidLen];
+            in.get(bs);
+            branchRegisterRequest.setXid(new String(bs, UTF8));
+        }
+        branchRegisterRequest.setBranchType(BranchType.get(in.get()));
+        short len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            branchRegisterRequest.setResourceId(new String(bs, UTF8));
+        }
+
+        int iLen = in.getInt();
+        if (iLen > 0) {
+            byte[] bs = new byte[iLen];
+            in.get(bs);
+            branchRegisterRequest.setLockKey(new String(bs, UTF8));
+        }
+
+        int applicationDataLen = in.getInt();
+        if (applicationDataLen > 0) {
+            byte[] bs = new byte[applicationDataLen];
+            in.get(bs);
+            branchRegisterRequest.setApplicationData(new String(bs, UTF8));
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..25f577c1c67d41c5216e1690e0f1a4de6e79beb6
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodec.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+
+/**
+ * The type Branch register response codec.
+ *
+ * @author zhangsen
+ */
+public class BranchRegisterResponseCodec extends AbstractTransactionResponseCodec implements Serializable {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchRegisterResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        super.encode(t, out);
+
+        BranchRegisterResponse branchRegisterResponse = (BranchRegisterResponse) t;
+        long branchId  = branchRegisterResponse.getBranchId();
+        out.putLong(branchId);
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        super.decode(t, in);
+
+        BranchRegisterResponse branchRegisterResponse = (BranchRegisterResponse) t;
+        branchRegisterResponse.setBranchId(in.getLong());
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..8cc8f53f775e91becdaaf5fd6ced44fc81b5ba67
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodec.java
@@ -0,0 +1,118 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.model.BranchStatus;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Branch report request codec.
+ *
+ * @author zhangsen
+ */
+public class BranchReportRequestCodec extends AbstractTransactionRequestToTCCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchReportRequest.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        BranchReportRequest branchReportRequest = (BranchReportRequest) t;
+        String xid = branchReportRequest.getXid();
+        long branchId = branchReportRequest.getBranchId();
+        BranchStatus status = branchReportRequest.getStatus();
+        String resourceId = branchReportRequest.getResourceId();
+        String applicationData = branchReportRequest.getApplicationData();
+        BranchType branchType = branchReportRequest.getBranchType();
+
+        byte[] applicationDataBytes = null;
+        if (applicationData != null) {
+            applicationDataBytes = applicationData.getBytes(UTF8);
+        }
+
+        // 1. xid
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+        // 2. Branch Id
+        out.putLong(branchId);
+        // 3. Branch Status
+        out.put((byte)status.getCode());
+        // 4. Resource Id
+        if (resourceId != null) {
+            byte[] bs = resourceId.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        // 5. Application Data
+        if (applicationData != null) {
+            out.putInt(applicationDataBytes.length);
+            if (applicationDataBytes.length > 0) {
+                out.put(applicationDataBytes);
+            }
+        } else {
+            out.putInt(0);
+        }
+        //6. branchType
+        out.put((byte)branchType.ordinal());
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        BranchReportRequest branchReportRequest = (BranchReportRequest) t;
+
+        short xidLen = in.getShort();
+        if (xidLen > 0) {
+            byte[] bs = new byte[xidLen];
+            in.get(bs);
+            branchReportRequest.setXid(new String(bs, UTF8));
+        }
+        branchReportRequest.setBranchId(in.getLong());
+        branchReportRequest.setStatus(BranchStatus.get(in.get()));
+        short len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            branchReportRequest.setResourceId(new String(bs, UTF8));
+        }
+
+        int iLen = in.getInt();
+        if (iLen > 0) {
+            byte[] bs = new byte[iLen];
+            in.get(bs);
+            branchReportRequest.setApplicationData(new String(bs, UTF8));
+        }
+        branchReportRequest.setBranchType(BranchType.get(in.get()));
+    }
+
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..056c6b5c707b52dce884c1ca9398a3d33f5f48cd
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.BranchReportResponse;
+
+/**
+ * The type Branch report response codec.
+ *
+ * @author zhangsen
+ */
+public class BranchReportResponseCodec extends AbstractTransactionResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchReportResponse.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bc845acf386c4bd3d3ca11765bc4f1993bf31a5
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+
+/**
+ * The type Branch rollback request codec.
+ *
+ * @author zhangsen
+ */
+public class BranchRollbackRequestCodec extends AbstractBranchEndRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchRollbackRequest.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..64a8410f6a462cc4bc514e05ca2a38a821b45dfc
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodec.java
@@ -0,0 +1,33 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+
+/**
+ * The type Branch rollback response codec.
+ *
+ * @author zhangsen
+ */
+public class BranchRollbackResponseCodec extends AbstractBranchEndResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return BranchRollbackResponse.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..c81dbe36229968dad83458f0502245ec481b6a8f
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodec.java
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Global begin request codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalBeginRequestCodec extends AbstractTransactionRequestToTCCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalBeginRequest.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        GlobalBeginRequest globalBeginRequest = (GlobalBeginRequest) t;
+        int timeout = globalBeginRequest.getTimeout();
+        String transactionName = globalBeginRequest.getTransactionName();
+
+        out.putInt(timeout);
+        if (transactionName != null) {
+            byte[] bs = transactionName.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        GlobalBeginRequest globalBeginRequest = (GlobalBeginRequest) t;
+
+        globalBeginRequest.setTimeout(in.getInt());
+        short len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            globalBeginRequest.setTransactionName(new String(bs, UTF8));
+        }
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf3819943a529e04639c8915dea918f621e5136b
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodec.java
@@ -0,0 +1,83 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Global begin response codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalBeginResponseCodec extends AbstractTransactionResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalBeginResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        super.encode(t, out);
+
+        GlobalBeginResponse globalBeginResponse = (GlobalBeginResponse) t;
+        String xid = globalBeginResponse.getXid();
+        String extraData = globalBeginResponse.getExtraData();
+
+        if (xid != null) {
+            byte[] bs = xid.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+
+        if (extraData != null) {
+            byte[] bs = extraData.getBytes(UTF8);
+            out.putShort((short)bs.length);
+            if (bs.length > 0) {
+                out.put(bs);
+            }
+        } else {
+            out.putShort((short)0);
+        }
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        super.decode(t, in);
+
+        GlobalBeginResponse globalBeginResponse = (GlobalBeginResponse) t;
+
+        short len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            globalBeginResponse.setXid(new String(bs, UTF8));
+        }
+
+        len = in.getShort();
+        if (len > 0) {
+            byte[] bs = new byte[len];
+            in.get(bs);
+            globalBeginResponse.setExtraData(new String(bs, UTF8));
+        }
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..d33be6939fdba53f2accf82c069618f6ed2ee832
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+
+/**
+ * The type Global commit request codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalCommitRequestCodec extends AbstractGlobalEndRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalCommitRequest.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e3b8d5c2a8d2c6670c52e66c03c5f3c28dc7f62
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodec.java
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+
+/**
+ * The type Global commit response codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalCommitResponseCodec extends AbstractGlobalEndResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalCommitResponse.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3e9bbe90ae046f2a224d71ef7596db87cb3f314
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+
+/**
+ * The type Global lock query request codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalLockQueryRequestCodec extends BranchRegisterRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalLockQueryRequest.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..98ffedcc20370379a34445333c1b2641bdf4a026
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodec.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+
+import java.nio.ByteBuffer;
+
+/**
+ * The type Global lock query response codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalLockQueryResponseCodec extends AbstractTransactionResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalLockQueryResponse.class;
+    }
+
+    @Override
+    public <T> void encode(T t, ByteBuffer out) {
+        super.encode(t, out);
+
+        GlobalLockQueryResponse globalLockQueryResponse = (GlobalLockQueryResponse) t;
+        boolean lockable = globalLockQueryResponse.isLockable();
+        out.putShort((short)(lockable ? 1 : 0));
+    }
+
+    @Override
+    public <T> void decode(T t, ByteBuffer in) {
+        super.decode(t, in);
+
+        GlobalLockQueryResponse globalLockQueryResponse = (GlobalLockQueryResponse) t;
+        globalLockQueryResponse.setLockable((in.getShort() == 1));
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9256cf6719e6d7d39aaff3815e9d10fced8f0fb
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodec.java
@@ -0,0 +1,31 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+
+/**
+ * The type Global rollback request codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalRollbackRequestCodec extends AbstractGlobalEndRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalRollbackRequest.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb93c2b6209ab4107e3123d412d1e277161462a0
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+
+/**
+ * The type Global rollback response codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalRollbackResponseCodec extends AbstractGlobalEndResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalRollbackResponse.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..8fbb98a2c107db45ff11a3c7e2f9d29eb309c0ba
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+
+/**
+ * The type Global status request codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalStatusRequestCodec extends AbstractGlobalEndRequestCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalStatusRequest.class;
+    }
+
+}
diff --git a/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodec.java b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodec.java
new file mode 100644
index 0000000000000000000000000000000000000000..958249474acb177498079f12c37d2c3e0c1ea282
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodec.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+
+/**
+ * The type Global status response codec.
+ *
+ * @author zhangsen
+ */
+public class GlobalStatusResponseCodec extends AbstractGlobalEndResponseCodec {
+
+    @Override
+    public Class<?> getMessageClassType() {
+        return GlobalStatusResponse.class;
+    }
+}
diff --git a/codec/seata-codec-seata/src/main/resources/META-INF/services/io.seata.core.codec.Codec b/codec/seata-codec-seata/src/main/resources/META-INF/services/io.seata.core.codec.Codec
new file mode 100644
index 0000000000000000000000000000000000000000..b870656b8208c04ee2544d2169c4364d93cd3737
--- /dev/null
+++ b/codec/seata-codec-seata/src/main/resources/META-INF/services/io.seata.core.codec.Codec
@@ -0,0 +1 @@
+io.seata.codec.seata.SeataCodec
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergeResultMessageCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergeResultMessageCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b76b5b4291316466e28eab3c8c36fed5b01d635
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergeResultMessageCodecTest.java
@@ -0,0 +1,85 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.AbstractResultMessage;
+import io.seata.core.protocol.MergeResultMessage;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Merge result message codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class MergeResultMessageCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        MergeResultMessage mergeResultMessage = new MergeResultMessage();
+        final AbstractResultMessage[] msgs = new AbstractResultMessage[2];
+        final GlobalBeginResponse globalBeginResponse1 = buildGlobalBeginResponse("a1");
+        final GlobalBeginResponse globalBeginResponse2 = buildGlobalBeginResponse("a2");
+        msgs[0] = globalBeginResponse1;
+        msgs[1] = globalBeginResponse2;
+        mergeResultMessage.setMsgs(msgs);
+
+        byte[] body = seataCodec.encode(mergeResultMessage);
+
+        MergeResultMessage mergeResultMessage2 = seataCodec.decode(body);
+        assertThat(mergeResultMessage2.msgs.length).isEqualTo(mergeResultMessage.msgs.length);
+
+        GlobalBeginResponse globalBeginResponse21 = (GlobalBeginResponse) mergeResultMessage2.msgs[0];
+        assertThat(globalBeginResponse21.getXid()).isEqualTo(globalBeginResponse1.getXid());
+        assertThat(globalBeginResponse21.getExtraData()).isEqualTo(globalBeginResponse1.getExtraData());
+        assertThat(globalBeginResponse21.getMsg()).isEqualTo(globalBeginResponse1.getMsg());
+        assertThat(globalBeginResponse21.getResultCode()).isEqualTo(globalBeginResponse1.getResultCode());
+        assertThat(globalBeginResponse21.getTransactionExceptionCode()).isEqualTo(globalBeginResponse1.getTransactionExceptionCode());
+
+
+        GlobalBeginResponse globalBeginResponse22 = (GlobalBeginResponse) mergeResultMessage2.msgs[1];
+        assertThat(globalBeginResponse22.getXid()).isEqualTo(globalBeginResponse2.getXid());
+        assertThat(globalBeginResponse22.getExtraData()).isEqualTo(globalBeginResponse2.getExtraData());
+        assertThat(globalBeginResponse22.getMsg()).isEqualTo(globalBeginResponse2.getMsg());
+        assertThat(globalBeginResponse22.getResultCode()).isEqualTo(globalBeginResponse2.getResultCode());
+        assertThat(globalBeginResponse22.getTransactionExceptionCode()).isEqualTo(globalBeginResponse2.getTransactionExceptionCode());
+
+    }
+
+    private GlobalBeginResponse buildGlobalBeginResponse(String xid) {
+        final GlobalBeginResponse globalBeginResponse = new GlobalBeginResponse();
+        globalBeginResponse.setXid(xid);
+        globalBeginResponse.setExtraData("data");
+        globalBeginResponse.setMsg("success");
+        globalBeginResponse.setResultCode(ResultCode.Failed);
+        globalBeginResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+        return globalBeginResponse;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergedWarpMessageCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergedWarpMessageCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c240663c1a0358dc094c7c754e77df93b0f50a8
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/MergedWarpMessageCodecTest.java
@@ -0,0 +1,77 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MergedWarpMessage;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.ArrayList;
+
+
+/**
+ * The type Merged warp message codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class MergedWarpMessageCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        MergedWarpMessage mergedWarpMessage = new MergedWarpMessage();
+        final ArrayList<AbstractMessage> msgs = new ArrayList<>();
+        final GlobalBeginRequest globalBeginRequest1 = buildGlobalBeginRequest("x1");
+        final GlobalBeginRequest globalBeginRequest2 = buildGlobalBeginRequest("x2");
+        msgs.add(globalBeginRequest1);
+        msgs.add(globalBeginRequest2);
+        mergedWarpMessage.msgs = msgs;
+
+        byte[] body = seataCodec.encode(mergedWarpMessage);
+
+        MergedWarpMessage mergedWarpMessage2 = seataCodec.decode(body);
+        assertThat(mergedWarpMessage2.msgs.size()).isEqualTo(mergedWarpMessage.msgs.size());
+
+        GlobalBeginRequest globalBeginRequest21 = (GlobalBeginRequest) mergedWarpMessage2.msgs.get(0);
+        assertThat(globalBeginRequest21.getTimeout()).isEqualTo(globalBeginRequest1.getTimeout());
+        assertThat(globalBeginRequest21.getTransactionName()).isEqualTo(globalBeginRequest1.getTransactionName());
+
+
+        GlobalBeginRequest globalBeginRequest22 = (GlobalBeginRequest) mergedWarpMessage2.msgs.get(1);
+        assertThat(globalBeginRequest22.getTimeout()).isEqualTo(globalBeginRequest2.getTimeout());
+        assertThat(globalBeginRequest22.getTransactionName()).isEqualTo(globalBeginRequest2.getTransactionName());
+
+    }
+
+    private GlobalBeginRequest buildGlobalBeginRequest(String name) {
+        final GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+        globalBeginRequest.setTransactionName(name);
+        globalBeginRequest.setTimeout(3000);
+        return globalBeginRequest;
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ca19b2edd57bf16de434ccc8d45791219e7d9241
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMRequestCodecTest.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.RegisterRMRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Register rm request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class RegisterRMRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec() {
+        RegisterRMRequest registerRMRequest = new RegisterRMRequest();
+        registerRMRequest.setResourceIds("a1,a2");
+        registerRMRequest.setApplicationId("abc");
+        registerRMRequest.setExtraData("abc124");
+        registerRMRequest.setTransactionServiceGroup("def");
+        registerRMRequest.setVersion("1");
+
+        byte[] body = seataCodec.encode(registerRMRequest);
+
+        RegisterRMRequest registerRMRequest2 = seataCodec.decode(body);
+        assertThat(registerRMRequest2.getResourceIds()).isEqualTo(registerRMRequest.getResourceIds());
+        assertThat(registerRMRequest2.getExtraData()).isEqualTo(registerRMRequest.getExtraData());
+        assertThat(registerRMRequest2.getApplicationId()).isEqualTo(registerRMRequest.getApplicationId());
+        assertThat(registerRMRequest2.getVersion()).isEqualTo(registerRMRequest.getVersion());
+        assertThat(registerRMRequest2.getTransactionServiceGroup()).isEqualTo(registerRMRequest.getTransactionServiceGroup());
+
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..484564b5bb8819153d6ed0f4dfe8ed52e64eea3d
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterRMResponseCodecTest.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.RegisterRMResponse;
+import io.seata.core.protocol.ResultCode;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+/**
+ * The type Register rm response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class RegisterRMResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        RegisterRMResponse registerRMResponse = new RegisterRMResponse();
+        registerRMResponse.setExtraData("abc123");
+        registerRMResponse.setIdentified(true);
+        registerRMResponse.setMsg("123456");
+        registerRMResponse.setVersion("12");
+        registerRMResponse.setResultCode(ResultCode.Failed);
+
+        byte[] body = seataCodec.encode(registerRMResponse);
+
+        RegisterRMResponse registerRMRespons2 = seataCodec.decode(body);
+
+        assertThat(registerRMRespons2.isIdentified()).isEqualTo(registerRMResponse.isIdentified());
+        assertThat(registerRMRespons2.getVersion()).isEqualTo(registerRMResponse.getVersion());
+
+//        Assert.assertEquals(registerRMRespons2.getExtraData(), registerRMResponse.getExtraData());
+//        Assert.assertEquals(registerRMRespons2.getMsg(), registerRMResponse.getMsg());
+//        Assert.assertEquals(registerRMRespons2.getByCode(), registerRMResponse.getByCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..60004798ca16e5124e258859cda80db5c86e6e7a
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMRequestCodecTest.java
@@ -0,0 +1,250 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.netty.buffer.ByteBuf;
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.AbstractIdentifyRequest;
+import io.seata.core.protocol.RegisterTMRequest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import static io.netty.buffer.Unpooled.buffer;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Register tm request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class RegisterTMRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    private static       RegisterTMRequest       registerTMRequest;
+    private static       AbstractIdentifyRequest air;
+    private static final String                  APP_ID    = "applicationId";
+    private static final String                  TSG       = "transactionServiceGroup";
+    private static final String                  ED        = "extraData";
+    private static final short                   TYPE_CODE = 101;
+    private static final ByteBuf                 BB        = buffer(128);
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec() {
+        RegisterTMRequest registerTMRequest = new RegisterTMRequest();
+        registerTMRequest.setApplicationId("abc");
+        registerTMRequest.setExtraData("abc123");
+        registerTMRequest.setTransactionServiceGroup("def");
+        registerTMRequest.setVersion("1");
+
+        byte[] body = seataCodec.encode(registerTMRequest);
+
+        RegisterTMRequest registerTMRequest2 = seataCodec.decode(body);
+
+        assertThat(registerTMRequest2.getApplicationId()).isEqualTo(registerTMRequest.getApplicationId());
+        assertThat(registerTMRequest2.getExtraData()).isEqualTo(registerTMRequest.getExtraData());
+        assertThat(registerTMRequest2.getTransactionServiceGroup()).isEqualTo(registerTMRequest.getTransactionServiceGroup());
+        assertThat(registerTMRequest2.getVersion()).isEqualTo(registerTMRequest.getVersion());
+    }
+
+    /**
+     * Constructor without arguments
+     **/
+    @BeforeAll
+    public static void setupNull() {
+        registerTMRequest = new RegisterTMRequest();
+        air = Mockito.mock(
+                AbstractIdentifyRequest.class,
+                Mockito.CALLS_REAL_METHODS);
+    }
+
+    /**
+     * Constructor with arguments
+     **/
+    @BeforeAll
+    public static void setupWithValues() {
+        registerTMRequest = new RegisterTMRequest(APP_ID, TSG, ED);
+        air = Mockito.mock(
+                AbstractIdentifyRequest.class,
+                Mockito.CALLS_REAL_METHODS);
+    }
+
+    /**
+     * Test get type code
+     **/
+    @Test
+    public void testGetTypeCode() {
+        Assertions.assertEquals(TYPE_CODE, registerTMRequest.getTypeCode());
+    }
+
+    /**
+     * Test toString having all the parameters initialized to null
+     */
+    @Test
+    public void testToStringNullValues() {
+        Assertions.assertEquals("RegisterTMRequest{" + "applicationId='" + null + '\'' + ", transactionServiceGroup='"
+                + null + '\'' + '}', registerTMRequest.toString());
+    }
+
+    /**
+     * Test decode method with empty parameter
+     */
+    @Test
+    public void testDecodeEmpty() {
+        BB.clear();
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeLessThanTwo() {
+        BB.clear();
+        for (int i = 0; i < 2; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeMoreThanThree() {
+        BB.clear();
+        for (int i = 0; i < 3; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeLessThanFour() {
+        BB.clear();
+        for (int i = 0; i < 4; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeMoreLessThanOne() {
+        BB.clear();
+        for (int i = 0; i < 1; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeMoreLessThanFourWithZero() {
+        BB.clear();
+        for (int i = 0; i < 4; i++) {
+            BB.writeZero(i);
+        }
+
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeTrueLessThanFive() {
+        BB.clear();
+        for (int i = 0; i < 4; i++) {
+            BB.writeZero(i);
+        }
+        for (int i = 4; i < 5; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+
+    /**
+     * Test decode method with initialized parameter
+     */
+    @Test
+    public void testDecodeTrueLessThanSixteen() {
+        BB.clear();
+        for (int i = 0; i < 15; i++) {
+            BB.writeZero(i);
+        }
+        for (int i = 15; i < 16; i++) {
+            BB.writeShort(i);
+        }
+        try {
+            seataCodec.decode(BB.array());
+            Assertions.fail();
+        } catch (Exception e) {
+            Assertions.assertTrue(e.getMessage().contains("not support "), "error data");
+        }
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3adafabb919d271864832f8a1c6910f9d2a07de3
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/RegisterTMResponseCodecTest.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.protocol.ResultCode;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Register tm response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class RegisterTMResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        RegisterTMResponse registerTMResponse = new RegisterTMResponse();
+        registerTMResponse.setVersion("abc");
+        registerTMResponse.setExtraData("abc123");
+        registerTMResponse.setIdentified(true);
+        registerTMResponse.setMsg("123456");
+        registerTMResponse.setResultCode(ResultCode.Failed);
+
+        byte[] bytes = seataCodec.encode(registerTMResponse);
+
+        RegisterTMResponse registerTMResponse2 = seataCodec.decode(bytes);
+
+        assertThat(registerTMResponse2.isIdentified()).isEqualTo(registerTMResponse.isIdentified());
+        assertThat(registerTMResponse2.getVersion()).isEqualTo(registerTMResponse.getVersion());
+
+//        Assert.assertEquals(registerTMResponse2.getExtraData(), registerTMResponse.getExtraData());
+//        Assert.assertEquals(registerTMResponse2.getMsg(), registerTMResponse.getMsg());
+//        Assert.assertEquals(registerTMResponse2.getByCode(), registerTMResponse.getByCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..fb2aedb7d05ee19ad03537978c7dfa2c9d8fa41f
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitRequestCodecTest.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch commit request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchCommitRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchCommitRequest branchCommitRequest = new BranchCommitRequest();
+        branchCommitRequest.setApplicationData("abc");
+        branchCommitRequest.setBranchId(123);
+        branchCommitRequest.setBranchType(BranchType.AT);
+        branchCommitRequest.setResourceId("t");
+        branchCommitRequest.setXid("a3");
+
+        byte[] bytes = seataCodec.encode(branchCommitRequest);
+
+        BranchCommitRequest branchCommitReques2 = seataCodec.decode(bytes);
+
+        assertThat(branchCommitReques2.getApplicationData()).isEqualTo(branchCommitRequest.getApplicationData());
+        assertThat(branchCommitReques2.getBranchType()).isEqualTo(branchCommitRequest.getBranchType());
+        assertThat(branchCommitReques2.getBranchId()).isEqualTo(branchCommitRequest.getBranchId());
+        assertThat(branchCommitReques2.getResourceId()).isEqualTo(branchCommitRequest.getResourceId());
+        assertThat(branchCommitReques2.getXid()).isEqualTo(branchCommitRequest.getXid());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6c35c11c900b9d926ecc6a8aef8b16148865c0b
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchCommitResponseCodecTest.java
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.BranchCommitResponse;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch commit response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchCommitResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchCommitResponse branchCommitResponse = new BranchCommitResponse();
+        branchCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+        branchCommitResponse.setBranchId(123);
+        branchCommitResponse.setBranchStatus(BranchStatus.PhaseOne_Done);
+        branchCommitResponse.setMsg("abc");
+        branchCommitResponse.setXid("a3");
+        branchCommitResponse.setResultCode(ResultCode.Failed);
+
+        byte[] bytes = seataCodec.encode(branchCommitResponse);
+
+        BranchCommitResponse branchCommitResponse2 = seataCodec.decode(bytes);
+
+        assertThat(branchCommitResponse2.getBranchStatus()).isEqualTo(branchCommitResponse.getBranchStatus());
+        assertThat(branchCommitResponse2.getBranchId()).isEqualTo(branchCommitResponse.getBranchId());
+        assertThat(branchCommitResponse2.getMsg()).isEqualTo(branchCommitResponse.getMsg());
+        assertThat(branchCommitResponse2.getXid()).isEqualTo(branchCommitResponse.getXid());
+        assertThat(branchCommitResponse2.getResultCode()).isEqualTo(branchCommitResponse.getResultCode());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8a9800bcc82f01c7df32ecb8e1b4b66409c50f8
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterRequestCodecTest.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchRegisterRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch register request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchRegisterRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchRegisterRequest branchRegisterRequest = new BranchRegisterRequest();
+        branchRegisterRequest.setBranchType(BranchType.AT);
+        branchRegisterRequest.setApplicationData("abc");
+        branchRegisterRequest.setLockKey("a:1,b:2");
+        branchRegisterRequest.setResourceId("124");
+        branchRegisterRequest.setXid("abc134");
+
+        byte[] bytes = seataCodec.encode(branchRegisterRequest);
+
+        BranchRegisterRequest branchRegisterRequest2 = seataCodec.decode(bytes);
+
+        assertThat(branchRegisterRequest2.getBranchType()).isEqualTo(branchRegisterRequest.getBranchType());
+        assertThat(branchRegisterRequest2.getApplicationData()).isEqualTo(branchRegisterRequest.getApplicationData());
+        assertThat(branchRegisterRequest2.getLockKey()).isEqualTo(branchRegisterRequest.getLockKey());
+        assertThat(branchRegisterRequest2.getResourceId()).isEqualTo(branchRegisterRequest.getResourceId());
+        assertThat(branchRegisterRequest2.getXid()).isEqualTo(branchRegisterRequest.getXid());
+
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b66b47fbf6da4b02208e7a413cec7575c4703702
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRegisterResponseCodecTest.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.BranchRegisterResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch register response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchRegisterResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchRegisterResponse branchRegisterResponse = new BranchRegisterResponse();
+        branchRegisterResponse.setBranchId(1346);
+        branchRegisterResponse.setMsg("addd");
+        branchRegisterResponse.setResultCode(ResultCode.Failed);
+        branchRegisterResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+
+        byte[] bytes = seataCodec.encode(branchRegisterResponse);
+
+        BranchRegisterResponse branchRegisterResponse2 = seataCodec.decode(bytes);
+
+        assertThat(branchRegisterResponse2.getBranchId()).isEqualTo(branchRegisterResponse.getBranchId());
+        assertThat(branchRegisterResponse2.getMsg()).isEqualTo(branchRegisterResponse.getMsg());
+        assertThat(branchRegisterResponse2.getResultCode()).isEqualTo(branchRegisterResponse.getResultCode());
+        assertThat(branchRegisterResponse2.getTransactionExceptionCode()).isEqualTo(branchRegisterResponse.getTransactionExceptionCode());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..301252f399e70602c5301bafe101646c6547f7de
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportRequestCodecTest.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchReportRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch report request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchReportRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchReportRequest branchReportRequest = new BranchReportRequest();
+        branchReportRequest.setBranchId(1346);
+        branchReportRequest.setBranchType(BranchType.TCC);
+        branchReportRequest.setApplicationData("acds");
+        branchReportRequest.setResourceId("aaa");
+        branchReportRequest.setStatus(BranchStatus.PhaseOne_Done);
+        branchReportRequest.setXid("abc123");
+
+        byte[] bytes = seataCodec.encode(branchReportRequest);
+
+        BranchReportRequest branchReportRequest2 = seataCodec.decode(bytes);
+        assertThat(branchReportRequest2.getBranchId()).isEqualTo(branchReportRequest.getBranchId());
+        assertThat(branchReportRequest2.getBranchType()).isEqualTo(branchReportRequest.getBranchType());
+        assertThat(branchReportRequest2.getApplicationData()).isEqualTo(branchReportRequest.getApplicationData());
+        assertThat(branchReportRequest2.getResourceId()).isEqualTo(branchReportRequest.getResourceId());
+        assertThat(branchReportRequest2.getStatus()).isEqualTo(branchReportRequest.getStatus());
+        assertThat(branchReportRequest2.getXid()).isEqualTo(branchReportRequest.getXid());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..61308ba13f238db77c80083f00b29010693350f5
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchReportResponseCodecTest.java
@@ -0,0 +1,58 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.BranchReportResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch report response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchReportResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchReportResponse branchReportResponse = new BranchReportResponse();
+        branchReportResponse.setMsg("abac");
+        branchReportResponse.setResultCode(ResultCode.Failed);
+        branchReportResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+
+        byte[] bytes = seataCodec.encode(branchReportResponse);
+
+        BranchReportResponse branchReportResponse2 = seataCodec.decode(bytes);
+
+        assertThat(branchReportResponse2.getMsg()).isEqualTo(branchReportResponse.getMsg());
+        assertThat(branchReportResponse2.getResultCode()).isEqualTo(branchReportResponse.getResultCode());
+        assertThat(branchReportResponse2.getTransactionExceptionCode()).isEqualTo(branchReportResponse.getTransactionExceptionCode());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2077d2031be8068bd8a2e213b629587820dabc68
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackRequestCodecTest.java
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.BranchRollbackRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch rollback request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchRollbackRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchRollbackRequest branchRollbackRequest = new BranchRollbackRequest();
+        branchRollbackRequest.setApplicationData("abcd");
+        branchRollbackRequest.setBranchId(112232);
+        branchRollbackRequest.setBranchType(BranchType.TCC);
+        branchRollbackRequest.setResourceId("343");
+        branchRollbackRequest.setXid("123");
+
+        byte[] bytes = seataCodec.encode(branchRollbackRequest);
+
+        BranchRollbackRequest branchRollbackRequest2 = seataCodec.decode(bytes);
+
+        assertThat(branchRollbackRequest2.getApplicationData()).isEqualTo(branchRollbackRequest.getApplicationData());
+        assertThat(branchRollbackRequest2.getBranchId()).isEqualTo(branchRollbackRequest.getBranchId());
+        assertThat(branchRollbackRequest2.getBranchType()).isEqualTo(branchRollbackRequest.getBranchType());
+        assertThat(branchRollbackRequest2.getResourceId()).isEqualTo(branchRollbackRequest.getResourceId());
+        assertThat(branchRollbackRequest2.getXid()).isEqualTo(branchRollbackRequest.getXid());
+
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ada6592591837d85bf211fca4868bb127cd5331c
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/BranchRollbackResponseCodecTest.java
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.BranchStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.BranchRollbackResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Branch rollback response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class BranchRollbackResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        BranchRollbackResponse branchRollbackResponse = new BranchRollbackResponse();
+        branchRollbackResponse.setBranchId(112232);
+        branchRollbackResponse.setXid("123");
+        branchRollbackResponse.setBranchStatus(BranchStatus.PhaseOne_Done);
+        branchRollbackResponse.setResultCode(ResultCode.Success);
+        branchRollbackResponse.setMsg("abc");
+        branchRollbackResponse.setTransactionExceptionCode(TransactionExceptionCode.BranchTransactionNotExist);
+
+        byte[] bytes = seataCodec.encode(branchRollbackResponse);
+
+        BranchRollbackResponse branchRollbackResponse2 = seataCodec.decode(bytes);
+
+        assertThat(branchRollbackResponse2.getBranchId()).isEqualTo(branchRollbackResponse.getBranchId());
+        assertThat(branchRollbackResponse2.getBranchStatus()).isEqualTo(branchRollbackResponse.getBranchStatus());
+        assertThat(branchRollbackResponse2.getResultCode()).isEqualTo(branchRollbackResponse.getResultCode());
+        assertThat(branchRollbackResponse2.getXid()).isEqualTo(branchRollbackResponse.getXid());
+        assertThat(branchRollbackResponse2.getBranchStatus()).isEqualTo(branchRollbackResponse.getBranchStatus());
+        assertThat(branchRollbackResponse2.getTransactionExceptionCode()).isEqualTo(branchRollbackResponse.getTransactionExceptionCode());
+
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..62fbdc19d542994c0c1be48555834971e7345fe4
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginRequestCodecTest.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global begin request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalBeginRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+        globalBeginRequest.setTimeout(10);
+        globalBeginRequest.setTransactionName("a24");
+
+        byte[] bytes = seataCodec.encode(globalBeginRequest);
+
+        GlobalBeginRequest globalBeginRequest2 = seataCodec.decode(bytes);
+        assertThat(globalBeginRequest2.getTransactionName()).isEqualTo(globalBeginRequest.getTransactionName());
+        assertThat(globalBeginRequest2.getTimeout()).isEqualTo(globalBeginRequest.getTimeout());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..23bae1e61eb1999dea04fed2bdaddc3659217975
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalBeginResponseCodecTest.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+/**
+ * The type Global begin response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalBeginResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalBeginResponse globalBeginResponse = new GlobalBeginResponse();
+        globalBeginResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotActive);
+        globalBeginResponse.setExtraData("absd");
+        globalBeginResponse.setXid("2454");
+        globalBeginResponse.setResultCode(ResultCode.Failed);
+        globalBeginResponse.setMsg("abcs");
+
+        byte[] bytes = seataCodec.encode(globalBeginResponse);
+
+        GlobalBeginResponse globalBeginResponse2 = seataCodec.decode(bytes);
+
+        assertThat(globalBeginResponse2.getTransactionExceptionCode()).isEqualTo(globalBeginResponse.getTransactionExceptionCode());
+        assertThat(globalBeginResponse2.getResultCode()).isEqualTo(globalBeginResponse.getResultCode());
+        assertThat(globalBeginResponse2.getXid()).isEqualTo(globalBeginResponse.getXid());
+        assertThat(globalBeginResponse2.getExtraData()).isEqualTo(globalBeginResponse.getExtraData());
+        assertThat(globalBeginResponse2.getMsg()).isEqualTo(globalBeginResponse.getMsg());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f65cd787d071972cfb22288081fb06f6c8819a7
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitRequestCodecTest.java
@@ -0,0 +1,56 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global commit request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalCommitRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalCommitRequest globalCommitRequest = new GlobalCommitRequest();
+        globalCommitRequest.setExtraData("aaaa");
+        globalCommitRequest.setXid("adf");
+
+        byte[] bytes = seataCodec.encode(globalCommitRequest);
+
+        GlobalCommitRequest globalCommitRequest2 = seataCodec.decode(bytes);
+
+        assertThat(globalCommitRequest2.getExtraData()).isEqualTo(globalCommitRequest.getExtraData());
+        assertThat(globalCommitRequest2.getXid()).isEqualTo(globalCommitRequest.getXid());
+
+    }
+
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b6ba625c6a3058a17647bc5b6d4da8d1e7f06e5
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalCommitResponseCodecTest.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+/**
+ * The type Global commit response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalCommitResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
+        globalCommitResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalCommitResponse.setMsg("aaa");
+        globalCommitResponse.setResultCode(ResultCode.Failed);
+        globalCommitResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionStatusInvalid);
+
+        byte[] bytes = seataCodec.encode(globalCommitResponse);
+
+        GlobalCommitResponse globalCommitResponse2 = seataCodec.decode(bytes);
+
+        assertThat(globalCommitResponse2.getGlobalStatus()).isEqualTo(globalCommitResponse.getGlobalStatus());
+        assertThat(globalCommitResponse2.getMsg()).isEqualTo(globalCommitResponse.getMsg());
+        assertThat(globalCommitResponse2.getResultCode()).isEqualTo(globalCommitResponse.getResultCode());
+        assertThat(globalCommitResponse2.getTransactionExceptionCode()).isEqualTo(globalCommitResponse.getTransactionExceptionCode());
+    }
+
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7c8e16f9d0a641834d2c3d66de14f458b6f7e36
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryRequestCodecTest.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+/**
+ * The type Global lock query request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalLockQueryRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalLockQueryRequest globalLockQueryRequest = new GlobalLockQueryRequest();
+        globalLockQueryRequest.setApplicationData("aaaa");
+        globalLockQueryRequest.setBranchType(BranchType.TCC);
+        globalLockQueryRequest.setLockKey("a:1,b,2");
+        globalLockQueryRequest.setXid("aaa");
+        globalLockQueryRequest.setResourceId("1s");
+
+        byte[] bytes = seataCodec.encode(globalLockQueryRequest);
+
+        GlobalLockQueryRequest globalLockQueryRequest2 = seataCodec.decode(bytes);
+
+        assertThat(globalLockQueryRequest2.getApplicationData()).isEqualTo(globalLockQueryRequest.getApplicationData());
+        assertThat(globalLockQueryRequest2.getBranchType()).isEqualTo(globalLockQueryRequest.getBranchType());
+        assertThat(globalLockQueryRequest2.getLockKey()).isEqualTo(globalLockQueryRequest.getLockKey());
+        assertThat(globalLockQueryRequest2.getResourceId()).isEqualTo(globalLockQueryRequest.getResourceId());
+        assertThat(globalLockQueryRequest2.getXid()).isEqualTo(globalLockQueryRequest.getXid());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..298431f1a865e5e7d5078f12be3b37ca613d0106
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalLockQueryResponseCodecTest.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global lock query response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalLockQueryResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalLockQueryResponse globalLockQueryResponse = new GlobalLockQueryResponse();
+        globalLockQueryResponse.setLockable(true);
+        globalLockQueryResponse.setMsg("aa");
+        globalLockQueryResponse.setResultCode(ResultCode.Failed);
+        globalLockQueryResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionStatusInvalid);
+
+        byte[] bytes = seataCodec.encode(globalLockQueryResponse);
+
+        GlobalLockQueryResponse globalLockQueryResponse2 = seataCodec.decode(bytes);
+
+        assertThat(globalLockQueryResponse2.isLockable()).isEqualTo(globalLockQueryResponse.isLockable());
+        assertThat(globalLockQueryResponse2.getResultCode()).isEqualTo(globalLockQueryResponse.getResultCode());
+        assertThat(globalLockQueryResponse2.getTransactionExceptionCode()).isEqualTo(globalLockQueryResponse.getTransactionExceptionCode());
+        assertThat(globalLockQueryResponse2.getMsg()).isEqualTo(globalLockQueryResponse.getMsg());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..29fd14650da1c3fde971258b622844bf806b62c8
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackRequestCodecTest.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global rollback request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalRollbackRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
+        globalRollbackRequest.setExtraData("aaaa");
+        globalRollbackRequest.setXid("aaaa");
+
+        byte[] bytes = seataCodec.encode(globalRollbackRequest);
+
+        GlobalRollbackRequest globalRollbackRequest2 = seataCodec.decode(bytes);
+        assertThat(globalRollbackRequest2.getXid()).isEqualTo(globalRollbackRequest.getXid());
+        assertThat(globalRollbackRequest2.getExtraData()).isEqualTo(globalRollbackRequest.getExtraData());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..dcbe4006aaa08d2d8ffbd1c050ad9ee44748ed05
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalRollbackResponseCodecTest.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global rollback response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalRollbackResponseCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalRollbackResponse globalRollbackResponse = new GlobalRollbackResponse();
+        globalRollbackResponse.setGlobalStatus(GlobalStatus.AsyncCommitting);
+        globalRollbackResponse.setMsg("aaa");
+        globalRollbackResponse.setResultCode(ResultCode.Failed);
+        globalRollbackResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotExist);
+
+        byte[] bytes = seataCodec.encode(globalRollbackResponse);
+
+        GlobalRollbackResponse globalRollbackResponse2 = seataCodec.decode(bytes);
+        assertThat(globalRollbackResponse2.getGlobalStatus()).isEqualTo(globalRollbackResponse.getGlobalStatus());
+        assertThat(globalRollbackResponse2.getMsg()).isEqualTo(globalRollbackResponse.getMsg());
+        assertThat(globalRollbackResponse2.getResultCode()).isEqualTo(globalRollbackResponse.getResultCode());
+        assertThat(globalRollbackResponse2.getTransactionExceptionCode()).isEqualTo(globalRollbackResponse.getTransactionExceptionCode());
+    }
+
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bafd72f260458132488e39f7a5df0babd887b3d5
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusRequestCodecTest.java
@@ -0,0 +1,52 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.protocol.transaction.GlobalStatusRequest;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global status request codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalStatusRequestCodecTest {
+
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalStatusRequest globalStatusRequest = new GlobalStatusRequest();
+        globalStatusRequest.setExtraData("aaaa");
+        globalStatusRequest.setXid("aaa123");
+
+        byte[] bytes = seataCodec.encode(globalStatusRequest);
+
+        GlobalStatusRequest globalStatusRequest2 = seataCodec.decode(bytes);
+        assertThat(globalStatusRequest2.getExtraData()).isEqualTo(globalStatusRequest.getExtraData());
+        assertThat(globalStatusRequest2.getXid()).isEqualTo(globalStatusRequest.getXid());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodecTest.java b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodecTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..37c8ed0c587ff1e7d128841df2bb947f1fba39e2
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/java/io/seata/codec/seata/protocol/transaction/GlobalStatusResponseCodecTest.java
@@ -0,0 +1,58 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.codec.seata.protocol.transaction;
+
+import io.seata.codec.seata.SeataCodec;
+import io.seata.core.exception.TransactionExceptionCode;
+import io.seata.core.model.GlobalStatus;
+import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.transaction.GlobalStatusResponse;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The type Global status response codec test.
+ *
+ * @author zhangsen
+ * @data 2019 /5/8
+ */
+public class GlobalStatusResponseCodecTest {
+    /**
+     * The Seata codec.
+     */
+    SeataCodec seataCodec = new SeataCodec();
+
+    /**
+     * Test codec.
+     */
+    @Test
+    public void test_codec(){
+        GlobalStatusResponse globalStatusResponse = new GlobalStatusResponse();
+        globalStatusResponse.setGlobalStatus(GlobalStatus.CommitRetrying);
+        globalStatusResponse.setMsg("aaaa");
+        globalStatusResponse.setResultCode(ResultCode.Failed);
+        globalStatusResponse.setTransactionExceptionCode(TransactionExceptionCode.GlobalTransactionNotExist);
+
+        byte[] bytes = seataCodec.encode(globalStatusResponse);
+
+        GlobalStatusResponse globalStatusResponse2 = seataCodec.decode(bytes);
+        assertThat(globalStatusResponse2.getGlobalStatus()).isEqualTo(globalStatusResponse.getGlobalStatus());
+        assertThat(globalStatusResponse2.getMsg()).isEqualTo(globalStatusResponse.getMsg());
+        assertThat(globalStatusResponse2.getTransactionExceptionCode()).isEqualTo(globalStatusResponse.getTransactionExceptionCode());
+        assertThat(globalStatusResponse2.getResultCode()).isEqualTo(globalStatusResponse.getResultCode());
+    }
+}
\ No newline at end of file
diff --git a/codec/seata-codec-seata/src/test/resources/file.conf b/codec/seata-codec-seata/src/test/resources/file.conf
new file mode 100644
index 0000000000000000000000000000000000000000..7ea53e40d02b707941673995f0e22173bbad6cf1
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/resources/file.conf
@@ -0,0 +1,74 @@
+transport {
+  # tcp udt unix-domain-socket
+  type = "TCP"
+  #NIO NATIVE
+  server = "NIO"
+  #enable heartbeat
+  heartbeat = true
+  #thread factory for netty
+  thread-factory {
+    boss-thread-prefix = "NettyBoss"
+    worker-thread-prefix = "NettyServerNIOWorker"
+    server-executor-thread-prefix = "NettyServerBizHandler"
+    share-boss-worker = false
+    client-selector-thread-prefix = "NettyClientSelector"
+    client-selector-thread-size = 1
+    client-worker-thread-prefix = "NettyClientWorkerThread"
+    # netty boss thread size,will not be used for UDT
+    boss-thread-size = 1
+    #auto default pin or 8
+    worker-thread-size = 8
+  }
+  serialization = "seata"
+  compressor = "none"
+}
+## transaction log store
+store {
+  ## store mode: file、db
+  mode = "file"
+
+  ## file store
+  file {
+    dir = "sessionStore"
+
+    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
+    max-branch-session-size = 16384
+    # globe session size , if exceeded throws exceptions
+    max-global-session-size = 512
+    # file buffer size , if exceeded allocate new buffer
+    file-write-buffer-cache-size = 16384
+    # when recover batch read size
+    session.reload.read_size = 100
+    # async, sync
+    flush-disk-mode = async
+  }
+
+  ## database store
+  db {
+    driver_class = ""
+    url = ""
+    user = ""
+    password = ""
+  }
+
+}
+
+service {
+  #vgroup->rgroup
+  vgroup_mapping.my_test_tx_group = "default"
+  #only support single node
+  default.grouplist = "127.0.0.1:8091"
+  #degrade current not support
+  enableDegrade = false
+  #disable
+  disable = false
+}
+
+client {
+  async.commit.buffer.limit = 10000
+  lock {
+    retry.internal = 10
+    retry.times = 30
+  }
+  report.retry.count = 5
+}
diff --git a/codec/seata-codec-seata/src/test/resources/registry.conf b/codec/seata-codec-seata/src/test/resources/registry.conf
new file mode 100644
index 0000000000000000000000000000000000000000..15677236a892397e6babed5c83f1263b842a56c2
--- /dev/null
+++ b/codec/seata-codec-seata/src/test/resources/registry.conf
@@ -0,0 +1,68 @@
+registry {
+  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
+  type = "file"
+
+  nacos {
+    serverAddr = "localhost"
+    namespace = "public"
+    cluster = "default"
+  }
+  eureka {
+    serviceUrl = "http://localhost:1001/eureka"
+    application = "default"
+    weight = "1"
+  }
+  redis {
+    serverAddr = "localhost:6379"
+    db = "0"
+  }
+  zk {
+    cluster = "default"
+    serverAddr = "127.0.0.1:2181"
+    session.timeout = 6000
+    connect.timeout = 2000
+  }
+  consul {
+    cluster = "default"
+    serverAddr = "127.0.0.1:8500"
+  }
+  etcd3 {
+    cluster = "default"
+    serverAddr = "http://localhost:2379"
+  }
+  sofa {
+    serverAddr = "127.0.0.1:9603"
+    application = "default"
+    region = "DEFAULT_ZONE"
+    datacenter = "DefaultDataCenter"
+    cluster = "default"
+    group = "SEATA_GROUP"
+    addressWaitTime = "3000"
+  }
+  file {
+    name = "file.conf"
+  }
+}
+
+config {
+  # file、nacos 、apollo、zk
+  type = "file"
+
+  nacos {
+    serverAddr = "localhost"
+    namespace = "public"
+    cluster = "default"
+  }
+  apollo {
+    app.id = "seata-server"
+    apollo.meta = "http://192.168.1.204:8801"
+  }
+  zk {
+    serverAddr = "127.0.0.1:2181"
+    session.timeout = 6000
+    connect.timeout = 2000
+  }
+  file {
+    name = "file.conf"
+  }
+}
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a89d7705466000b5463925e2f9dcf44788db3e85
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,12 @@
+coverage:
+  status:
+    patch:
+      default:
+        threshold: 1%
+ignore:
+  - "codec/seata-codec-protobuf/src/main/java/io/seata/codec/protobuf/generated"
+  - "test/.*"
+  - ".github/.*"
+  - ".mvn/.*"
+  - ".style/.*"
+  - "*.md"
\ No newline at end of file
diff --git a/common/src/main/java/io/seata/common/thread/NamedThreadFactory.java b/common/src/main/java/io/seata/common/thread/NamedThreadFactory.java
index e53b531765dce3d5ed9e96957def835514aba78d..fad15dfe1c84ea0175a1614e28e9cc104d7a95ca 100644
--- a/common/src/main/java/io/seata/common/thread/NamedThreadFactory.java
+++ b/common/src/main/java/io/seata/common/thread/NamedThreadFactory.java
@@ -45,6 +45,16 @@ public class NamedThreadFactory implements ThreadFactory {
         this.totalSize = totalSize;
     }
 
+    /**
+     * Instantiates a new Named thread factory.
+     *
+     * @param prefix      the prefix
+     * @param makeDaemons the make daemons
+     */
+    public NamedThreadFactory(String prefix, boolean makeDaemons) {
+        this(prefix, 0, makeDaemons);
+    }
+
     /**
      * Instantiates a new Named thread factory.
      *
diff --git a/common/src/main/java/io/seata/common/thread/PositiveAtomicCounter.java b/common/src/main/java/io/seata/common/thread/PositiveAtomicCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4c49c2290a4729734cc97b8bf8ac67bda358086
--- /dev/null
+++ b/common/src/main/java/io/seata/common/thread/PositiveAtomicCounter.java
@@ -0,0 +1,45 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.thread;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 计数器,从0开始,保证正数。
+ *
+ * @author Geng Zhang
+ */
+public class PositiveAtomicCounter {
+    private static final int    MASK = 0x7FFFFFFF;
+    private final AtomicInteger atom;
+
+    public PositiveAtomicCounter() {
+        atom = new AtomicInteger(0);
+    }
+
+    public final int incrementAndGet() {
+        return atom.incrementAndGet() & MASK;
+    }
+
+    public final int getAndIncrement() {
+        return atom.getAndIncrement() & MASK;
+    }
+
+    public int get() {
+        return atom.get() & MASK;
+    }
+
+}
\ No newline at end of file
diff --git a/common/src/main/java/io/seata/common/util/CodecUtils.java b/common/src/main/java/io/seata/common/util/CodecUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..83d1dd585790c51d22891e34f08b1aec88c57347
--- /dev/null
+++ b/common/src/main/java/io/seata/common/util/CodecUtils.java
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.util;
+
+/**
+ * @author Geng Zhang
+ * @since 0.7.0
+ */
+public class CodecUtils {
+
+    /**
+     * 一个byte存两个4bit的信息
+     *
+     * @param b 原始byte
+     * @return byte数组{<16,<16}
+     */
+    public static byte[] parseHigh4Low4Bytes(byte b) {
+        return new byte[]{
+                (byte) ((b >> 4)), // 右移4位,只取前4bit的值
+                (byte) ((b & 0x0f)) // 只取后面4bit的值,前面两位补0
+        };
+    }
+
+    /**
+     * 一个byte存两个4bit的信息
+     *
+     * @param high4 高4位 <16
+     * @param low4  低4位 <16
+     * @return 一个byte存两个4bit的信息
+     */
+    public static byte buildHigh4Low4Bytes(byte high4, byte low4) {
+        return (byte) ((high4 << 4) + low4);
+    }
+}
diff --git a/common/src/main/java/io/seata/common/util/CollectionUtils.java b/common/src/main/java/io/seata/common/util/CollectionUtils.java
index b929f3567df589a94f0d0c2e315cbf5f44367b14..3cafce06ba0e3f87ba45bac13cf5cba855145253 100644
--- a/common/src/main/java/io/seata/common/util/CollectionUtils.java
+++ b/common/src/main/java/io/seata/common/util/CollectionUtils.java
@@ -15,8 +15,12 @@
  */
 package io.seata.common.util;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * The type Collection utils.
@@ -107,4 +111,78 @@ public class CollectionUtils {
             }
         }
     }
+
+    private static final String KV_SPLIT = "=";
+
+    private static final String PAIR_SPLIT = "&";
+
+    /**
+     * Encode map to string
+     *
+     * @param map origin map
+     * @return String string
+     */
+    public static String encodeMap(Map<String, String> map) {
+        if (map == null) {
+            return null;
+        }
+        if (map.isEmpty()) {
+            return StringUtils.EMPTY;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            sb.append(entry.getKey()).append(KV_SPLIT).append(entry.getValue()).append(PAIR_SPLIT);
+        }
+        return sb.substring(0, sb.length() - 1);
+    }
+
+    /**
+     * Decode string to map
+     *
+     * @param data data
+     * @return map map
+     */
+    public static Map<String, String> decodeMap(String data) {
+        if (data == null) {
+            return null;
+        }
+        Map<String, String> map = new ConcurrentHashMap<>();
+        if (StringUtils.isBlank(data)) {
+            return map;
+        }
+        String[] kvPairs = data.split(PAIR_SPLIT);
+        if (kvPairs.length == 0) {
+            return map;
+        }
+        for (String kvPair : kvPairs) {
+            if (StringUtils.isNullOrEmpty(kvPair)) {
+                continue;
+            }
+            String[] kvs = kvPair.split(KV_SPLIT);
+            if (kvs.length != 2) {
+                continue;
+            }
+            map.put(kvs[0], kvs[1]);
+        }
+        return map;
+    }
+
+    /**
+     * To upper list list.
+     *
+     * @param sourceList the source list
+     * @return the list
+     */
+    public static List<String> toUpperList(List<String> sourceList) {
+        if (null == sourceList || sourceList.size() == 0) { return sourceList; }
+        List<String> destList = new ArrayList<>(sourceList.size());
+        for (String element : sourceList) {
+            if (null != element) {
+                destList.add(element.toUpperCase());
+            } else {
+                destList.add(element);
+            }
+        }
+        return destList;
+    }
 }
diff --git a/common/src/main/java/io/seata/common/util/NetUtil.java b/common/src/main/java/io/seata/common/util/NetUtil.java
index 5ffe7a4be7314060833458048bdeca60ed82076a..57b0e8cb0fa3cb4b93faa4739794c6700b4e74ec 100644
--- a/common/src/main/java/io/seata/common/util/NetUtil.java
+++ b/common/src/main/java/io/seata/common/util/NetUtil.java
@@ -15,6 +15,9 @@
  */
 package io.seata.common.util;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
@@ -22,9 +25,6 @@ import java.net.SocketAddress;
 import java.util.Enumeration;
 import java.util.regex.Pattern;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * The type Net util.
  *
@@ -48,7 +48,7 @@ public class NetUtil {
      * @return the string
      */
     public static String toStringAddress(SocketAddress address) {
-        return toStringAddress((InetSocketAddress)address);
+        return toStringAddress((InetSocketAddress) address);
     }
 
     /**
@@ -58,7 +58,7 @@ public class NetUtil {
      * @return the string
      */
     public static String toIpAddress(SocketAddress address) {
-        InetSocketAddress inetSocketAddress = (InetSocketAddress)address;
+        InetSocketAddress inetSocketAddress = (InetSocketAddress) address;
         return inetSocketAddress.getAddress().getHostAddress();
     }
 
@@ -196,12 +196,32 @@ public class NetUtil {
         }
     }
 
+    /**
+     * is valid address
+     *
+     * @param address
+     * @return true if the given address is valid
+     */
     private static boolean isValidAddress(InetAddress address) {
         if (address == null || address.isLoopbackAddress()) {
             return false;
         }
-        String name = address.getHostAddress();
-        return (name != null && !ANY_HOST.equals(name) && !LOCALHOST.equals(name) && IP_PATTERN.matcher(name)
-            .matches());
+        return isValidIp(address.getHostAddress(), false);
+    }
+
+    /**
+     * is valid IP
+     *
+     * @param ip
+     * @param validLocalAndAny Are 127.0.0.1 and 0.0.0.0 valid IPs?
+     * @return true if the given IP is valid
+     */
+    public static boolean isValidIp(String ip, boolean validLocalAndAny) {
+        if (validLocalAndAny) {
+            return ip != null && IP_PATTERN.matcher(ip).matches();
+        } else {
+            return (ip != null && !ANY_HOST.equals(ip) && !LOCALHOST.equals(ip) && IP_PATTERN.matcher(ip).matches());
+        }
+
     }
 }
diff --git a/common/src/main/java/io/seata/common/util/StringUtils.java b/common/src/main/java/io/seata/common/util/StringUtils.java
index 0b8e2d4e3e5fb04b6744ef0b14de1821496f7acd..55f5f66f6955c98d3a49e4ea597d465275991d67 100644
--- a/common/src/main/java/io/seata/common/util/StringUtils.java
+++ b/common/src/main/java/io/seata/common/util/StringUtils.java
@@ -37,6 +37,11 @@ public class StringUtils {
     private StringUtils() {
     }
 
+    /**
+     * empty string
+     */
+    public static final String EMPTY = "";
+    
     /**
      * Is empty boolean.
      *
diff --git a/common/src/test/java/io/seata/common/util/CodecUtilsTest.java b/common/src/test/java/io/seata/common/util/CodecUtilsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0cdf8174edc038f1d41c117d2a7e59c5c6b2d32f
--- /dev/null
+++ b/common/src/test/java/io/seata/common/util/CodecUtilsTest.java
@@ -0,0 +1,39 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.util;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Geng Zhang
+ */
+class CodecUtilsTest {
+
+    @Test
+    public void parseHigh4Low4Bytes() throws Exception {
+        byte b = 117; // = 7*16+5
+        byte[] bs = CodecUtils.parseHigh4Low4Bytes(b);
+        Assertions.assertEquals(bs[0], 7);
+        Assertions.assertEquals(bs[1], 5);
+    }
+
+    @Test
+    public void buildHigh4Low4Bytes() throws Exception {
+        byte bs = CodecUtils.buildHigh4Low4Bytes((byte) 7, (byte) 5);
+        Assertions.assertEquals(bs, (byte) 117);
+    }
+}
\ No newline at end of file
diff --git a/common/src/test/java/io/seata/common/util/CollectionUtilsTest.java b/common/src/test/java/io/seata/common/util/CollectionUtilsTest.java
index 5eaa53ad751c3ebbf5d6f81bebd338b65578278b..5c7b77af9fab3224dfba83b2f90b1cbb0824019e 100644
--- a/common/src/test/java/io/seata/common/util/CollectionUtilsTest.java
+++ b/common/src/test/java/io/seata/common/util/CollectionUtilsTest.java
@@ -15,17 +15,25 @@
  */
 package io.seata.common.util;
 
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
 /**
+ * The type Collection utils test.
+ *
  * @author Geng Zhang
  */
 public class CollectionUtilsTest {
 
+    /**
+     * Is size equals.
+     */
     @Test
     public void isSizeEquals() {
         List<String> list0 = new ArrayList<>();
@@ -40,4 +48,61 @@ public class CollectionUtilsTest {
         list1.add("111");
         Assertions.assertTrue(CollectionUtils.isSizeEquals(list0, list1));
     }
+
+    /**
+     * Encode map.
+     */
+    @Test
+    public void encodeMap() {
+        Map<String, String> map = null;
+        Assertions.assertNull(CollectionUtils.encodeMap(map));
+
+        map = new HashMap<>();
+        Assertions.assertEquals("", CollectionUtils.encodeMap(map));
+        map.put("x", "1");
+        Assertions.assertEquals("x=1", CollectionUtils.encodeMap(map));
+        map.put("y", "2");
+        Assertions.assertEquals("x=1&y=2", CollectionUtils.encodeMap(map));
+    }
+
+    /**
+     * Decode map.
+     */
+    @Test
+    public void decodeMap() {
+        Assertions.assertNull(CollectionUtils.decodeMap(null));
+
+        Map<String, String> map = CollectionUtils.decodeMap("");
+        Assertions.assertEquals(0, map.size());
+
+        map = CollectionUtils.decodeMap("x=1");
+        Assertions.assertEquals(1, map.size());
+        Assertions.assertEquals("1", map.get("x"));
+
+        map = CollectionUtils.decodeMap("x=1&y=2");
+        Assertions.assertEquals(2, map.size());
+        Assertions.assertEquals("2", map.get("y"));
+    }
+
+    /**
+     * Test to upper list.
+     */
+    @Test
+    public void testToUpperList() {
+        List<String> sourceList = null;
+        Assertions.assertNull(CollectionUtils.toUpperList(sourceList));
+        sourceList = new ArrayList<>();
+        Assertions.assertEquals(Collections.EMPTY_LIST, CollectionUtils.toUpperList(sourceList));
+        List<String> anotherList = new ArrayList<>();
+        sourceList.add("a");
+        anotherList.add("A");
+        sourceList.add("b");
+        anotherList.add("b");
+        sourceList.add("c");
+        anotherList.add("C");
+        Assertions.assertEquals(CollectionUtils.toUpperList(sourceList), CollectionUtils.toUpperList(anotherList));
+        anotherList.add("D");
+        Assertions.assertTrue(
+            CollectionUtils.toUpperList(anotherList).containsAll(CollectionUtils.toUpperList(sourceList)));
+    }
 }
\ No newline at end of file
diff --git a/common/src/test/java/io/seata/common/util/CompressUtilTest.java b/common/src/test/java/io/seata/common/util/CompressUtilTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..45bcee202e7e78d25b36d7981da5ce540d2b0588
--- /dev/null
+++ b/common/src/test/java/io/seata/common/util/CompressUtilTest.java
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.util;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class CompressUtilTest {
+
+    @Test
+    public void testCompress() throws IOException {
+        byte[] bytes = new byte[]{31, -117, 8, 0, 0, 0, 0, 0, 0, 0,
+                99, 100, 98, 6, 0, 29, -128, -68, 85, 3, 0, 0, 0};
+
+        Assertions.assertArrayEquals(bytes,
+                CompressUtil.compress(new byte[]{1, 2, 3}));
+    }
+
+    @Test
+    public void testUncompress() throws IOException {
+        byte[] bytes = new byte[]{31, -117, 8, 0, 0, 0, 0, 0, 0, 0,
+                99, 100, 98, 6, 0, 29, -128, -68, 85, 3, 0, 0, 0};
+
+        Assertions.assertArrayEquals(new byte[]{1, 2, 3},
+                CompressUtil.uncompress(bytes));
+    }
+
+    @Test
+    public void testIsCompressData() {
+        Assertions.assertFalse(CompressUtil.isCompressData(null));
+        Assertions.assertFalse(CompressUtil.isCompressData(new byte[0]));
+        Assertions.assertFalse(CompressUtil.isCompressData(new byte[]{31, 11}));
+        Assertions.assertFalse(
+                CompressUtil.isCompressData(new byte[]{31, 11, 0}));
+
+        Assertions.assertTrue(
+                CompressUtil.isCompressData(new byte[]{31, -117, 0}));
+    }
+}
diff --git a/common/src/test/java/io/seata/common/util/DurationUtilTest.java b/common/src/test/java/io/seata/common/util/DurationUtilTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1736a34123157e00a4c6bc74b158fff74bbab897
--- /dev/null
+++ b/common/src/test/java/io/seata/common/util/DurationUtilTest.java
@@ -0,0 +1,50 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.util;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class DurationUtilTest {
+
+    @Test
+    public void testParse() {
+        Assertions.assertNull(DurationUtil.parse("d"));
+        Assertions.assertNull(DurationUtil.parse("h"));
+        Assertions.assertNull(DurationUtil.parse("m"));
+        Assertions.assertNull(DurationUtil.parse("s"));
+        Assertions.assertNull(DurationUtil.parse("ms"));
+
+        Assertions.assertEquals(-1L, DurationUtil.parse("").getSeconds());
+        Assertions.assertEquals(0L, DurationUtil.parse("8").getSeconds());
+        Assertions.assertEquals(0L, DurationUtil.parse("8ms").getSeconds());
+        Assertions.assertEquals(8L, DurationUtil.parse("8s").getSeconds());
+        Assertions.assertEquals(480L, DurationUtil.parse("8m").getSeconds());
+        Assertions.assertEquals(28800L, DurationUtil.parse("8h").getSeconds());
+        Assertions.assertEquals(691200L,
+                DurationUtil.parse("8d").getSeconds());
+    }
+
+    @Test
+    public void testParseThrowException() {
+        Assertions.assertThrows(UnsupportedOperationException.class,
+                () -> DurationUtil.parse("a"));
+
+        Assertions.assertThrows(UnsupportedOperationException.class,
+                () -> DurationUtil.parse("as"));
+
+    }
+}
diff --git a/common/src/test/java/io/seata/common/util/ReflectionUtilTest.java b/common/src/test/java/io/seata/common/util/ReflectionUtilTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..15411c773e0da9083438bccfdc7680ca61ffff93
--- /dev/null
+++ b/common/src/test/java/io/seata/common/util/ReflectionUtilTest.java
@@ -0,0 +1,101 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.common.util;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ReflectionUtilTest {
+
+    @Test
+    public void testGetClassByName() throws ClassNotFoundException {
+        Assertions.assertEquals(String.class,
+                ReflectionUtil.getClassByName("java.lang.String"));
+    }
+
+    @Test
+    public void testGetFieldValue() throws
+            NoSuchFieldException, IllegalAccessException {
+        Assertions.assertEquals("d",
+                ReflectionUtil.getFieldValue(new DurationUtil(), "DAY_UNIT"));
+
+        Assertions.assertThrows(NoSuchFieldException.class,
+                () -> ReflectionUtil.getFieldValue(new Object(), "A1B2C3"));
+    }
+
+    @Test
+    public void testInvokeMethod() throws NoSuchMethodException,
+            IllegalAccessException, InvocationTargetException {
+        Assertions.assertEquals(0, ReflectionUtil.invokeMethod("", "length"));
+        Assertions.assertEquals(3,
+                ReflectionUtil.invokeMethod("foo", "length"));
+
+        Assertions.assertThrows(NoSuchMethodException.class,
+                () -> ReflectionUtil.invokeMethod(new String(), "size"));
+    }
+
+    @Test
+    public void testInvokeMethod2() throws NoSuchMethodException,
+            IllegalAccessException, InvocationTargetException {
+        Assertions.assertEquals(0, ReflectionUtil
+                .invokeMethod("", "length", null, null));
+        Assertions.assertEquals(3, ReflectionUtil
+                .invokeMethod("foo", "length", null, null));
+
+        Assertions.assertThrows(NoSuchMethodException.class, () -> ReflectionUtil
+                .invokeMethod(new String(), "size", null, null));
+    }
+
+    @Test
+    public void testInvokeMethod3() throws NoSuchMethodException,
+            IllegalAccessException, InvocationTargetException {
+        Assertions.assertEquals("0", ReflectionUtil.invokeStaticMethod(
+                String.class, "valueOf",
+                new Class<?>[]{int.class}, new Object[]{0}));
+        Assertions.assertEquals("123", ReflectionUtil.invokeStaticMethod(
+                String.class, "valueOf",
+                new Class<?>[]{int.class}, new Object[]{123}));
+
+        Assertions.assertThrows(NoSuchMethodException.class, () -> ReflectionUtil
+                .invokeStaticMethod(String.class, "size", null, null));
+    }
+
+    @Test
+    public void testGetMethod() throws NoSuchMethodException {
+        Assertions.assertEquals("public int java.lang.String.length()",
+                ReflectionUtil.getMethod(String.class, "length", null)
+                        .toString());
+        Assertions.assertEquals("public char java.lang.String.charAt(int)",
+                ReflectionUtil.getMethod(String.class, "charAt",
+                        new Class<?>[]{int.class}).toString());
+
+        Assertions.assertThrows(NoSuchMethodException.class,
+                () -> ReflectionUtil.getMethod(String.class, "size", null));
+    }
+
+    @Test
+    public void testGetInterfaces() {
+        Assertions.assertArrayEquals(new Object[]{Serializable.class},
+                ReflectionUtil.getInterfaces(Serializable.class).toArray());
+
+        Assertions.assertArrayEquals(new Object[]{
+                        Serializable.class, Comparable.class, CharSequence.class},
+                ReflectionUtil.getInterfaces(String.class).toArray());
+    }
+}
diff --git a/config/seata-config-core/src/main/java/io/seata/config/ConfigurationFactory.java b/config/seata-config-core/src/main/java/io/seata/config/ConfigurationFactory.java
index 7267cfa30554fc14b4852c3235dfb0a2956ee0af..ac8bad43388afafa4395b18192838a67851e015b 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/ConfigurationFactory.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/ConfigurationFactory.java
@@ -27,19 +27,19 @@ import java.util.Objects;
  * @author Geng Zhang
  */
 public final class ConfigurationFactory {
-    private static final String REGISTRY_CONF = "registry.conf";
     private static final String REGISTRY_CONF_PREFIX = "registry";
     private static final String REGISTRY_CONF_SUFFIX = ".conf";
     private static final String ENV_SYSTEM_KEY = "SEATA_CONFIG_ENV";
-    private static final String ENV_PROPERTY_KEY = "env";
+    private static final String ENV_PROPERTY_KEY = "seataConfigEnv";
     private static final String DEFAULT_ENV_VALUE = "default";
     /**
      * The constant FILE_INSTANCE.
      */
     private static String ENV_VALUE;
+
     static {
         String env = System.getenv(ENV_SYSTEM_KEY);
-        if(env != null && System.getProperty(ENV_PROPERTY_KEY) == null){
+        if (env != null && System.getProperty(ENV_PROPERTY_KEY) == null) {
             //Help users get
             System.setProperty(ENV_PROPERTY_KEY, env);
         }
diff --git a/config/seata-config-core/src/main/resources/file.conf b/config/seata-config-core/src/main/resources/file.conf
index 42133e2a77f96967712a25fbba40a0d83d6a2144..f4fb96bc87978354ef019abe147d3069b0bba2fe 100644
--- a/config/seata-config-core/src/main/resources/file.conf
+++ b/config/seata-config-core/src/main/resources/file.conf
@@ -19,6 +19,12 @@ transport {
     #auto default pin or 8
     worker-thread-size = 8
   }
+  shutdown {
+    # when destroy server, wait seconds
+    wait = 3
+  }
+  serialization = "seata"
+  compressor = "none"
 }
 ## transaction log store
 store {
@@ -73,5 +79,5 @@ client {
 
 transaction {
   undo.data.validation = true
-  undo.log.serialization = fastjson
+  undo.log.serialization = "jackson"
 }
diff --git a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfiguration.java
similarity index 99%
rename from config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java
rename to config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfiguration.java
index 59e9ae3e63d6d4ab3d5947128fbdfebf3cb1ddc2..bce6cf0c4fa2860809515055573cf4d265c2d00c 100644
--- a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java
+++ b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfiguration.java
@@ -13,7 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.config.etcd;
+package io.seata.config.etcd3;
 
 import io.etcd.jetcd.ByteSequence;
 import io.etcd.jetcd.Client;
diff --git a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.java b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfigurationProvider.java
similarity index 97%
rename from config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.java
rename to config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfigurationProvider.java
index acb7e28db96a3a89bd13a14dccbab2043b1894b0..dd146a42a9f751bc413a7c1806edff1232afc749 100644
--- a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.java
+++ b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd3/EtcdConfigurationProvider.java
@@ -13,7 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.config.etcd;
+package io.seata.config.etcd3;
 
 import io.seata.common.loader.LoadLevel;
 import io.seata.config.Configuration;
diff --git a/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider b/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
index ce01ac197600438bb941beca28567a291b72de90..22d67274f7efa664e4d7ae3d7c2bfddc0d82dee8 100644
--- a/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
+++ b/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
@@ -1 +1 @@
-io.seata.config.etcd.EtcdConfigurationProvider
\ No newline at end of file
+io.seata.config.etcd3.EtcdConfigurationProvider
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index 9670f9fd495d0d935e7c983159d6dbdc0149e737..5657a7df99e26dc1ac454a469627a0971c597a8f 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -60,12 +60,19 @@
             <artifactId>commons-dbcp</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+        </dependency>
     </dependencies>
 
 </project>
diff --git a/core/src/main/java/io/seata/core/protocol/MessageCodec.java b/core/src/main/java/io/seata/core/codec/Codec.java
similarity index 61%
rename from core/src/main/java/io/seata/core/protocol/MessageCodec.java
rename to core/src/main/java/io/seata/core/codec/Codec.java
index 8a77602fc3a884fecdb26c1646c4658b03ad126c..aa2712bdb042820ebef200e718a77b1b6cb19808 100644
--- a/core/src/main/java/io/seata/core/protocol/MessageCodec.java
+++ b/core/src/main/java/io/seata/core/codec/Codec.java
@@ -13,36 +13,31 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.core.protocol;
-
-import io.netty.buffer.ByteBuf;
+package io.seata.core.codec;
 
 /**
- * The interface Message codec.
+ * The interface Codec.
  *
- * @author jimin.jm @alibaba-inc.com
- * @date 2018 /9/14
+ * @author zhangsen
+ * @data 2019 /5/6
  */
-public interface MessageCodec {
-    /**
-     * Gets type code.
-     *
-     * @return the type code
-     */
-    short getTypeCode();
+public interface Codec {
 
     /**
-     * Encode byte [ ].
+     * Encode object to byte[].
      *
+     * @param <T> the type parameter
+     * @param t   the t
      * @return the byte [ ]
      */
-    byte[] encode();
+    <T> byte[] encode(T t);
 
     /**
-     * Decode boolean.
+     * Decode t from byte[].
      *
-     * @param in the in
-     * @return the boolean
+     * @param <T>   the type parameter
+     * @param bytes the bytes
+     * @return the t
      */
-    boolean decode(ByteBuf in);
+    <T> T decode(byte[] bytes);
 }
diff --git a/core/src/main/java/io/seata/core/codec/CodecFactory.java b/core/src/main/java/io/seata/core/codec/CodecFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..97b8cbbf14d7df4721a1c50abf7d8136032d7f25
--- /dev/null
+++ b/core/src/main/java/io/seata/core/codec/CodecFactory.java
@@ -0,0 +1,77 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.codec;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import io.seata.common.loader.EnhancedServiceLoader;
+
+/**
+ * The type Codec factory.
+ *
+ * @author zhangsen
+ * @data 2019 /5/6
+ */
+public class CodecFactory {
+
+    /**
+     * The constant CODEC_MAP.
+     */
+    protected static final Map<CodecType, Codec> CODEC_MAP = new ConcurrentHashMap<CodecType, Codec>();
+
+    /**
+     * Get codec codec.
+     *
+     * @param codec the code
+     * @return the codec
+     */
+    public static synchronized Codec getCodec(byte codec) {
+        CodecType codecType = CodecType.getByCode(codec);
+        if (CODEC_MAP.get(codecType) != null) {
+            return CODEC_MAP.get(codecType);
+        }
+        Codec codecImpl = EnhancedServiceLoader.load(Codec.class, codecType.name());
+        CODEC_MAP.put(codecType, codecImpl);
+        return codecImpl;
+    }
+
+    /**
+     * Encode byte [ ].
+     *
+     * @param <T>  the type parameter
+     * @param codec the codec
+     * @param t    the t
+     * @return the byte [ ]
+     */
+    public static <T> byte[] encode(byte codec, T t) {
+        return getCodec(codec).encode(t);
+    }
+
+    /**
+     * Decode t.
+     *
+     * @param <T>   the type parameter
+     * @param codec  the code
+     * @param bytes the bytes
+     * @return the t
+     */
+    public static <T> T decode(byte codec, byte[] bytes){
+        return getCodec(codec).decode(bytes);
+    }
+
+
+}
diff --git a/core/src/main/java/io/seata/core/codec/CodecType.java b/core/src/main/java/io/seata/core/codec/CodecType.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f98d0c0be450e95c94b2c38393bbab389dadacc
--- /dev/null
+++ b/core/src/main/java/io/seata/core/codec/CodecType.java
@@ -0,0 +1,83 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.codec;
+
+/**
+ * The enum serialize type.
+ *
+ * @author leizhiyuan
+ */
+public enum CodecType {
+
+    /**
+     * The seata.
+     * <p>
+     * Math.pow(2, 0)
+     */
+    SEATA((byte)0x1),
+
+    /**
+     * The protobuf.
+     * <p>
+     * Math.pow(2, 1)
+     */
+    PROTOBUF((byte)0x2);
+
+    private final byte code;
+
+    CodecType(final byte code) {
+        this.code = code;
+    }
+
+    /**
+     * Gets result code.
+     *
+     * @param code the code
+     * @return the result code
+     */
+    public static CodecType getByCode(int code) {
+        for (CodecType b : CodecType.values()) {
+            if (code == b.code) {
+                return b;
+            }
+        }
+        throw new IllegalArgumentException("unknown codec:" + code);
+    }
+
+    /**
+     * Gets result code.
+     *
+     * @param name the name
+     * @return the result code
+     */
+    public static CodecType getByName(String name) {
+        for (CodecType b : CodecType.values()) {
+            if (b.name().equalsIgnoreCase(name)) {
+                return b;
+            }
+        }
+        throw new IllegalArgumentException("unknown codec:" + name);
+    }
+
+    /**
+     * Gets code.
+     *
+     * @return the code
+     */
+    public byte getCode() {
+        return code;
+    }
+}
diff --git a/core/src/main/java/io/seata/core/codec/CompressorType.java b/core/src/main/java/io/seata/core/codec/CompressorType.java
new file mode 100644
index 0000000000000000000000000000000000000000..71111a95ff548bb9f88734c449be1f86cf11e449
--- /dev/null
+++ b/core/src/main/java/io/seata/core/codec/CompressorType.java
@@ -0,0 +1,77 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.codec;
+
+/**
+ * @author Geng Zhang
+ */
+public enum CompressorType {
+
+    /**
+     * Not compress
+     */
+    NONE((byte) 0),
+
+    /**
+     * The gzip.
+     */
+    GZIP((byte) 1);
+
+    private final byte code;
+
+    CompressorType(final byte code) {
+        this.code = code;
+    }
+
+    /**
+     * Gets result code.
+     *
+     * @param code the code
+     * @return the result code
+     */
+    public static CompressorType getByCode(int code) {
+        for (CompressorType b : CompressorType.values()) {
+            if (code == b.code) {
+                return b;
+            }
+        }
+        throw new IllegalArgumentException("unknown codec:" + code);
+    }
+
+    /**
+     * Gets result code.
+     *
+     * @param name the code
+     * @return the result code
+     */
+    public static CompressorType getByName(String name) {
+        for (CompressorType b : CompressorType.values()) {
+            if (b.name().equalsIgnoreCase(name)) {
+                return b;
+            }
+        }
+        throw new IllegalArgumentException("unknown codec:" + name);
+    }
+
+    /**
+     * Gets code.
+     *
+     * @return the code
+     */
+    public byte getCode() {
+        return code;
+    }
+}
diff --git a/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java b/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
index e50b19dfc7138ea54589dedf17c323ff8a928277..99de0be73e3011d9076c13775e77de2d4377d5c8 100644
--- a/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
+++ b/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
@@ -70,6 +70,11 @@ public class ConfigurationKeys {
      */
     public static final String CLIENT_PREFIX = "client.";
 
+    /**
+     * The constant TRANSPORT_PREFIX.
+     */
+    public static final String TRANSPORT_PREFIX = "transport.";
+
     /**
      * The constant CLIENT_ASYNC_COMMIT_BUFFER_LIMIT.
      */
@@ -93,6 +98,19 @@ public class ConfigurationKeys {
      */
     public static final String CLIENT_REPORT_RETRY_COUNT = CLIENT_PREFIX + "report.retry.count";
 
+
+    /**
+     * The constant SERIALIZE_FOR_RPC.
+     */
+    public static final String SERIALIZE_FOR_RPC = TRANSPORT_PREFIX + "serialization";
+
+    /**
+     * The constant COMPRESSOR_FOR_RPC.
+     * 
+     * @since 0.7.0
+     */
+    public static final String COMPRESSOR_FOR_RPC = TRANSPORT_PREFIX + "compressor";
+
     /**
      * The constant STORE_DB_GLOBAL_TABLE.
      */
@@ -162,7 +180,7 @@ public class ConfigurationKeys {
     /**
      * The constant LOCK_DB_TABLE.
      */
-    public static final String LOCK_DB_TABLE  = "lock.db.lock-table";
+    public static final String LOCK_DB_TABLE  = "store.db.lock-table";
 
     /**
      * The constant LOCK_DB_DEFAULT_TABLE.
@@ -202,4 +220,24 @@ public class ConfigurationKeys {
      * The constant TRANSACTION_UNDO_LOG_SERIALIZATION.
      */
     public static final String TRANSACTION_UNDO_LOG_SERIALIZATION = TRANSACTION_PREFIX + "undo.log.serialization";
+
+    /**
+     * The constant METRICS_PREFIX.
+     */
+    public static final String METRICS_PREFIX = "metrics.";
+
+    /**
+     * The constant METRICS_ENABLED.
+     */
+    public static final String METRICS_ENABLED = "enabled";
+
+    /**
+     * The constant METRICS_REGISTRY_TYPE.
+     */
+    public static final String METRICS_REGISTRY_TYPE = "registry-type";
+
+    /**
+     * The constant METRICS_EXPORTER_LIST.
+     */
+    public static final String METRICS_EXPORTER_LIST = "exporter-list";
 }
diff --git a/core/src/main/java/io/seata/core/event/Event.java b/core/src/main/java/io/seata/core/event/Event.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e73fd7855e384341fffaf0f9333e2d88ed9efbc
--- /dev/null
+++ b/core/src/main/java/io/seata/core/event/Event.java
@@ -0,0 +1,24 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.event;
+
+/**
+ * The base interface for seata event.
+ *
+ * @author zhengyangyong
+ */
+public interface Event {
+}
diff --git a/core/src/main/java/io/seata/core/event/EventBus.java b/core/src/main/java/io/seata/core/event/EventBus.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed0327c4f13b2e8528ae07c908015101feed76dc
--- /dev/null
+++ b/core/src/main/java/io/seata/core/event/EventBus.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.event;
+
+/**
+ * The interface fot event bus.
+ *
+ * @author zhengyangyong
+ */
+public interface EventBus {
+    void register(Object subscriber);
+
+    void unregister(Object subscriber);
+
+    void post(Event event);
+}
diff --git a/core/src/main/java/io/seata/core/event/GlobalTransactionEvent.java b/core/src/main/java/io/seata/core/event/GlobalTransactionEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..9538f69e73642df125ed31465cf29b9e13a409d0
--- /dev/null
+++ b/core/src/main/java/io/seata/core/event/GlobalTransactionEvent.java
@@ -0,0 +1,95 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.event;
+
+import io.seata.core.model.GlobalStatus;
+
+/**
+ * Event data for global transaction.
+ *
+ * @author zhengyangyong
+ */
+public class GlobalTransactionEvent implements Event {
+    public static final String ROLE_TC = "tc";
+
+    public static final String ROLE_TM = "tm";
+
+    public static final String ROLE_RM = "rm";
+
+    /**
+     * Transaction Id
+     */
+    private long id;
+
+    /**
+     * Source Role
+     */
+    private final String role;
+
+    /**
+     * Transaction Name
+     */
+    private final String name;
+
+    /**
+     * Transaction Begin Time
+     */
+    private final Long beginTime;
+
+    /**
+     * Transaction End Time (If Transaction do not committed or rollbacked, null)
+     */
+    private final Long endTime;
+
+    /**
+     * Transaction Status
+     */
+    private final GlobalStatus status;
+
+    public long getId() {
+        return id;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Long getBeginTime() {
+        return beginTime;
+    }
+
+    public Long getEndTime() {
+        return endTime;
+    }
+
+    public GlobalStatus getStatus() {
+        return status;
+    }
+
+    public GlobalTransactionEvent(long id, String role, String name, Long beginTime, Long endTime,
+                                  GlobalStatus status) {
+        this.id = id;
+        this.role = role;
+        this.name = name;
+        this.beginTime = beginTime;
+        this.endTime = endTime;
+        this.status = status;
+    }
+}
diff --git a/core/src/main/java/io/seata/core/event/GuavaEventBus.java b/core/src/main/java/io/seata/core/event/GuavaEventBus.java
new file mode 100644
index 0000000000000000000000000000000000000000..bd9e470b87af0a5599dbc53bb361bd6d63908b80
--- /dev/null
+++ b/core/src/main/java/io/seata/core/event/GuavaEventBus.java
@@ -0,0 +1,44 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.event;
+
+/**
+ * Default event bus implement with Guava EventBus.
+ *
+ * @author zhengyangyong
+ */
+public class GuavaEventBus implements EventBus {
+    private final com.google.common.eventbus.EventBus eventBus;
+
+    public GuavaEventBus(String identifier) {
+        this.eventBus = new com.google.common.eventbus.EventBus(identifier);
+    }
+
+    @Override
+    public void register(Object subscriber) {
+        this.eventBus.register(subscriber);
+    }
+
+    @Override
+    public void unregister(Object subscriber) {
+        this.eventBus.unregister(subscriber);
+    }
+
+    @Override
+    public void post(Event event) {
+        this.eventBus.post(event);
+    }
+}
diff --git a/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java b/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
index a8501be705ae2c278b4b787cefd27de54e899694..20c9af7d7ba35925b086f55216cf442258502c98 100644
--- a/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
+++ b/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
@@ -20,6 +20,8 @@ import io.seata.config.ConfigurationFactory;
 import io.seata.core.protocol.ResultCode;
 import io.seata.core.protocol.transaction.AbstractTransactionRequest;
 import io.seata.core.protocol.transaction.AbstractTransactionResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The type Abstract exception handler.
@@ -28,6 +30,8 @@ import io.seata.core.protocol.transaction.AbstractTransactionResponse;
  */
 public abstract class AbstractExceptionHandler {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExceptionHandler.class);
+
     /**
      * The constant CONFIG.
      */
@@ -113,8 +117,10 @@ public abstract class AbstractExceptionHandler {
             callback.execute(request, response);
             callback.onSuccess(request, response);
         } catch (TransactionException tex) {
+            LOGGER.error("Catch TransactionException while do RPC, request: {}", request, tex);
             callback.onTransactionException(request, response, tex);
         } catch (RuntimeException rex) {
+            LOGGER.error("Catch RuntimeException while do RPC, request: {}", request, rex);
             callback.onException(request, response, rex);
         }
     }
diff --git a/core/src/main/java/io/seata/core/lock/LockMode.java b/core/src/main/java/io/seata/core/lock/LockMode.java
index f1a11d0b9ea30818009ebd3324c7ebf155f7334e..e905730f97400a838ad4253395620357100d0dd7 100644
--- a/core/src/main/java/io/seata/core/lock/LockMode.java
+++ b/core/src/main/java/io/seata/core/lock/LockMode.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.lock;
 
+import io.seata.core.store.StoreMode;
+
 /**
  * lock mode
  *
@@ -24,14 +26,14 @@ package io.seata.core.lock;
 public enum LockMode {
 
     /**
-     * store the lock in memory of server
+     * store the lock in user's database
      */
-    MEMORY,
+    LOCAL,
 
     /**
-     * store the lock in db of server
+     * store the lock in seata's server
      */
-    DB;
+    REMOTE;
 
 
 }
diff --git a/core/src/main/java/io/seata/core/protocol/AbstractIdentifyRequest.java b/core/src/main/java/io/seata/core/protocol/AbstractIdentifyRequest.java
index f7b0d197239cc59cbd08bb8843457d2aa1ebbda0..f38ff0ddeb9a28611af734a15314d55079b87a86 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractIdentifyRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractIdentifyRequest.java
@@ -15,11 +15,6 @@
  */
 package io.seata.core.protocol;
 
-import java.nio.ByteBuffer;
-
-import io.netty.buffer.ByteBuf;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The type Abstract identify request.
@@ -28,8 +23,6 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class AbstractIdentifyRequest extends AbstractMessage {
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractIdentifyRequest.class);
-
     /**
      * The Version.
      */
@@ -146,125 +139,4 @@ public abstract class AbstractIdentifyRequest extends AbstractMessage {
         this.extraData = extraData;
     }
 
-    /**
-     * The Byte buffer.
-     */
-    public ByteBuffer byteBuffer = ByteBuffer.allocate(10 * 1024);
-
-    /**
-     * Do encode.
-     */
-    protected void doEncode() {
-        byteBuffer.clear();
-        if (this.version != null) {
-            byte[] bs = version.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        if (this.applicationId != null) {
-            byte[] bs = applicationId.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        if (this.transactionServiceGroup != null) {
-            byte[] bs = transactionServiceGroup.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        if (this.extraData != null) {
-            byte[] bs = extraData.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-    }
-
-    private final byte[] flushEncode() {
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        byteBuffer.clear(); // >?
-        return content;
-    }
-
-    @Override
-    public final byte[] encode() {
-        doEncode();
-        return flushEncode();
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-
-        short len;
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (in.readableBytes() < len) {
-            return false;
-        }
-        byte[] bs = new byte[len];
-        in.readBytes(bs);
-        this.setVersion(new String(bs, UTF8));
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (in.readableBytes() < len) {
-            return false;
-        }
-        bs = new byte[len];
-        in.readBytes(bs);
-        this.setApplicationId(new String(bs, UTF8));
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (in.readableBytes() < len) {
-            return false;
-        }
-        bs = new byte[len];
-        in.readBytes(bs);
-        this.setTransactionServiceGroup(new String(bs, UTF8));
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (in.readableBytes() >= len) {
-            bs = new byte[len];
-            in.readBytes(bs);
-            this.setExtraData(new String(bs, UTF8));
-        } else {
-            //maybe null
-        }
-
-        return true;
-    }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/AbstractIdentifyResponse.java b/core/src/main/java/io/seata/core/protocol/AbstractIdentifyResponse.java
index f74691833f070a1c9cf601f3a466c692c2960491..e258e7a92f5d6a5f152c94245fcb8afd43e24e0a 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractIdentifyResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractIdentifyResponse.java
@@ -15,8 +15,6 @@
  */
 package io.seata.core.protocol;
 
-import io.netty.buffer.ByteBuf;
-
 /**
  * The type Abstract identify response.
  *
@@ -84,41 +82,6 @@ public abstract class AbstractIdentifyResponse extends AbstractResultMessage {
         this.identified = identified;
     }
 
-    @Override
-    public void doEncode() {
-        //        super.doEncode();
-        byteBuffer.put(this.identified ? (byte)1 : (byte)0);
-        if (this.version != null) {
-            byte[] bs = version.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        if (in.readableBytes() < 3) {
-            return false;
-        }
-        this.identified = in.readByte() == 1;
-        short len = in.readShort();
-        if (len <= 0) {
-            return false;
-        }
-        if (in.readableBytes() < len) {
-            return false;
-        }
-        byte[] bs = new byte[len];
-        in.readBytes(bs);
-        this.setVersion(new String(bs, UTF8));
-        return true;
-
-    }
 
     @Override
     public String toString() {
diff --git a/core/src/main/java/io/seata/core/protocol/AbstractMessage.java b/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
index f15c5367cb31e342094241c07d89023edbca7cec..99abb70dee2cfabd3e6bdd670b21127207e6c0af 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
@@ -15,30 +15,14 @@
  */
 package io.seata.core.protocol;
 
-import java.io.Serializable;
-import java.nio.charset.Charset;
-
-import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.seata.common.Constants;
-import io.seata.core.protocol.transaction.BranchCommitRequest;
-import io.seata.core.protocol.transaction.BranchCommitResponse;
-import io.seata.core.protocol.transaction.BranchRegisterRequest;
-import io.seata.core.protocol.transaction.BranchRegisterResponse;
-import io.seata.core.protocol.transaction.BranchReportRequest;
-import io.seata.core.protocol.transaction.BranchReportResponse;
-import io.seata.core.protocol.transaction.BranchRollbackRequest;
-import io.seata.core.protocol.transaction.BranchRollbackResponse;
-import io.seata.core.protocol.transaction.GlobalBeginRequest;
-import io.seata.core.protocol.transaction.GlobalBeginResponse;
-import io.seata.core.protocol.transaction.GlobalCommitRequest;
-import io.seata.core.protocol.transaction.GlobalCommitResponse;
-import io.seata.core.protocol.transaction.GlobalLockQueryRequest;
-import io.seata.core.protocol.transaction.GlobalLockQueryResponse;
-import io.seata.core.protocol.transaction.GlobalRollbackRequest;
-import io.seata.core.protocol.transaction.GlobalRollbackResponse;
-import io.seata.core.protocol.transaction.GlobalStatusRequest;
-import io.seata.core.protocol.transaction.GlobalStatusResponse;
+import io.seata.common.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.nio.charset.Charset;
 
 /**
  * The type Abstract message.
@@ -46,108 +30,11 @@ import io.seata.core.protocol.transaction.GlobalStatusResponse;
  * @author jimin.jm @alibaba-inc.com
  * @date 2018 /9/14
  */
-public abstract class AbstractMessage implements MessageCodec, Serializable {
-    private static final long serialVersionUID = -1441020418526899889L;
+public abstract class AbstractMessage implements MessageTypeAware, Serializable {
 
-    /**
-     * The constant TYPE_GLOBAL_BEGIN.
-     */
-    public static final short TYPE_GLOBAL_BEGIN = 1;
-    /**
-     * The constant TYPE_GLOBAL_BEGIN_RESULT.
-     */
-    public static final short TYPE_GLOBAL_BEGIN_RESULT = 2;
-    /**
-     * The constant TYPE_GLOBAL_COMMIT.
-     */
-    public static final short TYPE_GLOBAL_COMMIT = 7;
-    /**
-     * The constant TYPE_GLOBAL_COMMIT_RESULT.
-     */
-    public static final short TYPE_GLOBAL_COMMIT_RESULT = 8;
-    /**
-     * The constant TYPE_GLOBAL_ROLLBACK.
-     */
-    public static final short TYPE_GLOBAL_ROLLBACK = 9;
-    /**
-     * The constant TYPE_GLOBAL_ROLLBACK_RESULT.
-     */
-    public static final short TYPE_GLOBAL_ROLLBACK_RESULT = 10;
-    /**
-     * The constant TYPE_GLOBAL_STATUS.
-     */
-    public static final short TYPE_GLOBAL_STATUS = 15;
-    /**
-     * The constant TYPE_GLOBAL_STATUS_RESULT.
-     */
-    public static final short TYPE_GLOBAL_STATUS_RESULT = 16;
-    /**
-     * The constant TYPE_GLOBAL_LOCK_QUERY.
-     */
-    public static final short TYPE_GLOBAL_LOCK_QUERY = 21;
-    /**
-     * The constant TYPE_GLOBAL_LOCK_QUERY_RESULT.
-     */
-    public static final short TYPE_GLOBAL_LOCK_QUERY_RESULT = 22;
+    protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractMessage.class);
 
-    /**
-     * The constant TYPE_BRANCH_COMMIT.
-     */
-    public static final short TYPE_BRANCH_COMMIT = 3;
-    /**
-     * The constant TYPE_BRANCH_COMMIT_RESULT.
-     */
-    public static final short TYPE_BRANCH_COMMIT_RESULT = 4;
-    /**
-     * The constant TYPE_BRANCH_ROLLBACK.
-     */
-    public static final short TYPE_BRANCH_ROLLBACK = 5;
-    /**
-     * The constant TYPE_BRANCH_ROLLBACK_RESULT.
-     */
-    public static final short TYPE_BRANCH_ROLLBACK_RESULT = 6;
-    /**
-     * The constant TYPE_BRANCH_REGISTER.
-     */
-    public static final short TYPE_BRANCH_REGISTER = 11;
-    /**
-     * The constant TYPE_BRANCH_REGISTER_RESULT.
-     */
-    public static final short TYPE_BRANCH_REGISTER_RESULT = 12;
-    /**
-     * The constant TYPE_BRANCH_STATUS_REPORT.
-     */
-    public static final short TYPE_BRANCH_STATUS_REPORT = 13;
-    /**
-     * The constant TYPE_BRANCH_STATUS_REPORT_RESULT.
-     */
-    public static final short TYPE_BRANCH_STATUS_REPORT_RESULT = 14;
-
-    /**
-     * The constant TYPE_SEATA_MERGE.
-     */
-    public static final short TYPE_SEATA_MERGE = 59;
-    /**
-     * The constant TYPE_SEATA_MERGE_RESULT.
-     */
-    public static final short TYPE_SEATA_MERGE_RESULT = 60;
-
-    /**
-     * The constant TYPE_REG_CLT.
-     */
-    public static final short TYPE_REG_CLT = 101;
-    /**
-     * The constant TYPE_REG_CLT_RESULT.
-     */
-    public static final short TYPE_REG_CLT_RESULT = 102;
-    /**
-     * The constant TYPE_REG_RM.
-     */
-    public static final short TYPE_REG_RM = 103;
-    /**
-     * The constant TYPE_REG_RM_RESULT.
-     */
-    public static final short TYPE_REG_RM_RESULT = 104;
+    protected static final long serialVersionUID = -1441020418526899889L;
 
     /**
      * The constant UTF8.
@@ -189,118 +76,7 @@ public abstract class AbstractMessage implements MessageCodec, Serializable {
     }
 
     @Override
-    public boolean decode(ByteBuf in) {
-        return false;
-    }
-
-    /**
-     * Gets msg instance by code.
-     *
-     * @param typeCode the type code
-     * @return the msg instance by code
-     */
-    public static MessageCodec getMsgInstanceByCode(short typeCode) {
-        MessageCodec msgCodec = null;
-        switch (typeCode) {
-            case AbstractMessage.TYPE_SEATA_MERGE:
-                msgCodec = new MergedWarpMessage();
-                break;
-            case AbstractMessage.TYPE_SEATA_MERGE_RESULT:
-                msgCodec = new MergeResultMessage();
-                break;
-            case AbstractMessage.TYPE_REG_CLT:
-                msgCodec = new RegisterTMRequest();
-                break;
-            case AbstractMessage.TYPE_REG_CLT_RESULT:
-                msgCodec = new RegisterTMResponse();
-                break;
-            case AbstractMessage.TYPE_REG_RM:
-                msgCodec = new RegisterRMRequest();
-                break;
-            case AbstractMessage.TYPE_REG_RM_RESULT:
-                msgCodec = new RegisterRMResponse();
-                break;
-            case AbstractMessage.TYPE_BRANCH_COMMIT:
-                msgCodec = new BranchCommitRequest();
-                break;
-            case AbstractMessage.TYPE_BRANCH_ROLLBACK:
-                msgCodec = new BranchRollbackRequest();
-                break;
-            default:
-                break;
-        }
-
-        if (null != msgCodec) {
-            return msgCodec;
-        }
-
-        try {
-            msgCodec = (MessageCodec)getMergeRequestInstanceByCode(typeCode);
-        } catch (Exception exx) {
-
-        }
-        if (null != msgCodec) {
-            return msgCodec;
-        }
-
-        return (MessageCodec)getMergeResponseInstanceByCode(typeCode);
-    }
-
-    /**
-     * Gets merge request instance by code.
-     *
-     * @param typeCode the type code
-     * @return the merge request instance by code
-     */
-    public static MergedMessage getMergeRequestInstanceByCode(int typeCode) {
-        switch (typeCode) {
-            case AbstractMessage.TYPE_GLOBAL_BEGIN:
-                return new GlobalBeginRequest();
-            case AbstractMessage.TYPE_GLOBAL_COMMIT:
-                return new GlobalCommitRequest();
-            case AbstractMessage.TYPE_GLOBAL_ROLLBACK:
-                return new GlobalRollbackRequest();
-            case AbstractMessage.TYPE_GLOBAL_STATUS:
-                return new GlobalStatusRequest();
-            case AbstractMessage.TYPE_GLOBAL_LOCK_QUERY:
-                return new GlobalLockQueryRequest();
-            case AbstractMessage.TYPE_BRANCH_REGISTER:
-                return new BranchRegisterRequest();
-            case AbstractMessage.TYPE_BRANCH_STATUS_REPORT:
-                return new BranchReportRequest();
-            default:
-                throw new IllegalArgumentException("not support typeCode," + typeCode);
-        }
-    }
-
-    /**
-     * Gets merge response instance by code.
-     *
-     * @param typeCode the type code
-     * @return the merge response instance by code
-     */
-    public static MergedMessage getMergeResponseInstanceByCode(int typeCode) {
-        switch (typeCode) {
-            case AbstractMessage.TYPE_GLOBAL_BEGIN_RESULT:
-                return new GlobalBeginResponse();
-            case AbstractMessage.TYPE_GLOBAL_COMMIT_RESULT:
-                return new GlobalCommitResponse();
-            case AbstractMessage.TYPE_GLOBAL_ROLLBACK_RESULT:
-                return new GlobalRollbackResponse();
-            case AbstractMessage.TYPE_GLOBAL_STATUS_RESULT:
-                return new GlobalStatusResponse();
-            case AbstractMessage.TYPE_GLOBAL_LOCK_QUERY_RESULT:
-                return new GlobalLockQueryResponse();
-            case AbstractMessage.TYPE_BRANCH_REGISTER_RESULT:
-                return new BranchRegisterResponse();
-            case AbstractMessage.TYPE_BRANCH_STATUS_REPORT_RESULT:
-                return new BranchReportResponse();
-            case AbstractMessage.TYPE_BRANCH_COMMIT_RESULT:
-                return new BranchCommitResponse();
-            case AbstractMessage.TYPE_BRANCH_ROLLBACK_RESULT:
-                return new BranchRollbackResponse();
-            default:
-                throw new IllegalArgumentException("not support typeCode," + typeCode);
-        }
+    public String toString() {
+        return StringUtils.toString(this);
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/AbstractResultMessage.java b/core/src/main/java/io/seata/core/protocol/AbstractResultMessage.java
index 187eb10dc29295b7cc2ae01bc1632560881940e6..04258a75ef54cf450629a25744fd7e971a9a681a 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractResultMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractResultMessage.java
@@ -15,25 +15,17 @@
  */
 package io.seata.core.protocol;
 
-import java.nio.ByteBuffer;
-
-import io.netty.buffer.ByteBuf;
-
 /**
  * The type Abstract result message.
  *
  * @author jimin.jm @alibaba-inc.com
  * @date 2018 /9/14
  */
-public abstract class AbstractResultMessage extends AbstractMessage implements MergedMessage {
-    private static final long serialVersionUID = 6540352050650203313L;
+public abstract class AbstractResultMessage extends AbstractMessage  {
 
     private ResultCode resultCode;
 
-    /**
-     * The Byte buffer.
-     */
-    public ByteBuffer byteBuffer = ByteBuffer.allocate(512);
+    private String msg;
 
     /**
      * Gets result code.
@@ -53,8 +45,6 @@ public abstract class AbstractResultMessage extends AbstractMessage implements M
         this.resultCode = resultCode;
     }
 
-    private String msg;
-
     /**
      * Gets msg.
      *
@@ -73,81 +63,4 @@ public abstract class AbstractResultMessage extends AbstractMessage implements M
         this.msg = msg;
     }
 
-    /**
-     * Do encode.
-     */
-    protected void doEncode() {
-        byteBuffer.put((byte)resultCode.ordinal());
-        if (resultCode == ResultCode.Failed) {
-            if (getMsg() != null) {
-                String msg;
-                if (getMsg().length() > 128) {
-                    msg = getMsg().substring(0, 128);
-                } else {
-                    msg = getMsg();
-                }
-                byte[] bs = msg.getBytes(UTF8);
-                if (bs.length > 400 && getMsg().length() > 64) {
-                    msg = getMsg().substring(0, 64);
-                    bs = msg.getBytes(UTF8);
-                }
-                byteBuffer.putShort((short)bs.length);
-                if (bs.length > 0) {
-                    byteBuffer.put(bs);
-                }
-            } else {
-                byteBuffer.putShort((short)0);
-            }
-        }
-    }
-
-    private final byte[] flushEncode() {
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        byteBuffer.clear(); // >?
-        return content;
-    }
-
-    @Override
-    public final byte[] encode() {
-        doEncode();
-        return flushEncode();
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        setResultCode(ResultCode.get(byteBuffer.get()));
-        if (resultCode == ResultCode.Failed) {
-            short len = byteBuffer.getShort();
-            if (len > 0) {
-                byte[] msg = new byte[len];
-                byteBuffer.get(msg);
-                this.setMsg(new String(msg, UTF8));
-            }
-        }
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        if (in.readableBytes() < 1) {
-            return false;
-        }
-        setResultCode(ResultCode.get(in.readByte()));
-        if (resultCode == ResultCode.Failed) {
-            if (in.readableBytes() < 2) {
-                return false;
-            }
-            short len = in.readShort();
-            if (in.readableBytes() < len) {
-                return false;
-            }
-            if (len > 0) {
-                byte[] msg = new byte[len];
-                in.readBytes(msg);
-                this.setMsg(new String(msg, UTF8));
-            }
-        }
-        return true;
-    }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/HeartbeatMessage.java b/core/src/main/java/io/seata/core/protocol/HeartbeatMessage.java
index e25e34b1485ff44e6924729c0059002cc6e234eb..6271ffe86ead2854135e92b88559b06e8fee6124 100644
--- a/core/src/main/java/io/seata/core/protocol/HeartbeatMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/HeartbeatMessage.java
@@ -25,7 +25,7 @@ import java.io.Serializable;
  */
 public class HeartbeatMessage implements Serializable {
     private static final long serialVersionUID = -985316399527884899L;
-    private boolean pingOrPong = true;
+    private boolean ping = true;
     /**
      * The constant PING.
      */
@@ -35,12 +35,20 @@ public class HeartbeatMessage implements Serializable {
      */
     public static final HeartbeatMessage PONG = new HeartbeatMessage(false);
 
-    private HeartbeatMessage(boolean pingOrPong) {
-        this.pingOrPong = pingOrPong;
+    private HeartbeatMessage(boolean ping) {
+        this.ping = ping;
     }
 
     @Override
     public String toString() {
-        return this.pingOrPong ? "services ping" : "services pong";
+        return this.ping ? "services ping" : "services pong";
+    }
+
+    public boolean isPing() {
+        return ping;
+    }
+
+    public void setPing(boolean ping) {
+        this.ping = ping;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/MergeResultMessage.java b/core/src/main/java/io/seata/core/protocol/MergeResultMessage.java
index 79bc2678cc01101ac18bd47aeee73876078e7618..1ec0afacbf2930e16d6c8889bbdb1e9412e374a0 100644
--- a/core/src/main/java/io/seata/core/protocol/MergeResultMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/MergeResultMessage.java
@@ -15,11 +15,6 @@
  */
 package io.seata.core.protocol;
 
-import java.nio.ByteBuffer;
-
-import io.netty.buffer.ByteBuf;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * The type Merge result message.
@@ -28,12 +23,11 @@ import org.slf4j.LoggerFactory;
  * @date 2018 /10/10
  */
 public class MergeResultMessage extends AbstractMessage implements MergeMessage {
-    private static final long serialVersionUID = -7719219648774528552L;
+
     /**
      * The Msgs.
      */
     public AbstractResultMessage[] msgs;
-    private static final Logger LOGGER = LoggerFactory.getLogger(MergeResultMessage.class);
 
     /**
      * Get msgs abstract result message [ ].
@@ -55,60 +49,7 @@ public class MergeResultMessage extends AbstractMessage implements MergeMessage
 
     @Override
     public short getTypeCode() {
-        return TYPE_SEATA_MERGE_RESULT;
-    }
-
-    @Override
-    public byte[] encode() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(msgs.length * 1024);
-        byteBuffer.putShort((short)msgs.length);
-        for (AbstractMessage msg : msgs) {
-            byte[] data = msg.encode();
-            byteBuffer.putShort(msg.getTypeCode());
-            byteBuffer.put(data);
-        }
-
-        byteBuffer.flip();
-        int length = byteBuffer.limit();
-        byte[] content = new byte[length + 4];
-        intToBytes(length, content, 0);
-        byteBuffer.get(content, 4, length);
-        if (msgs.length > 20) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("msg in one services merge packet:" + msgs.length
-                    + ",buffer size:" + content.length);
-            }
-        }
-        return content;
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        if (in.readableBytes() < 4) { return false; }
-
-        int length = in.readInt();
-        if (in.readableBytes() < length) { return false; }
-        byte[] buffer = new byte[length];
-        in.readBytes(buffer);
-        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
-        decode(byteBuffer);
-        return true;
-    }
-
-    /**
-     * Decode.
-     *
-     * @param byteBuffer the byte buffer
-     */
-    public void decode(ByteBuffer byteBuffer) {
-        short msgNum = byteBuffer.getShort();
-        msgs = new AbstractResultMessage[msgNum];
-        for (int idx = 0; idx < msgNum; idx++) {
-            short typeCode = byteBuffer.getShort();
-            MergedMessage message = getMergeResponseInstanceByCode(typeCode);
-            message.decode(byteBuffer);
-            msgs[idx] = (AbstractResultMessage)message;
-        }
+        return MessageType.TYPE_SEATA_MERGE_RESULT;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/MergedWarpMessage.java b/core/src/main/java/io/seata/core/protocol/MergedWarpMessage.java
index 6b4c3f847e2d882d41f58c3757a11b7721da85a5..89ca1e544a11ef0e39ce7d8a4d9bca953d727b6c 100644
--- a/core/src/main/java/io/seata/core/protocol/MergedWarpMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/MergedWarpMessage.java
@@ -16,14 +16,9 @@
 package io.seata.core.protocol;
 
 import java.io.Serializable;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
 
-import io.netty.buffer.ByteBuf;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * The type Merged warp message.
  *
@@ -31,73 +26,19 @@ import org.slf4j.LoggerFactory;
  * @date 2018 /10/9
  */
 public class MergedWarpMessage extends AbstractMessage implements Serializable, MergeMessage {
-    private static final long serialVersionUID = -5758802337446717090L;
+
     /**
      * The Msgs.
      */
-    public List<AbstractMessage> msgs = new ArrayList<AbstractMessage>();
+    public List<AbstractMessage> msgs = new ArrayList<>();
     /**
      * The Msg ids.
      */
-    public List<Long> msgIds = new ArrayList<Long>();
-    private static final Logger LOGGER = LoggerFactory.getLogger(MergedWarpMessage.class);
+    public List<Integer> msgIds = new ArrayList<>();
 
     @Override
     public short getTypeCode() {
-        return TYPE_SEATA_MERGE;
-    }
-
-    @Override
-    public byte[] encode() {
-        int bufferSize = msgs.size() * 1024;
-        ByteBuffer byteBuffer = ByteBuffer.allocate(bufferSize);
-        byteBuffer.putShort((short)msgs.size());
-        for (AbstractMessage msg : msgs) {
-            //msg.setChannelHandlerContext(ctx);
-            byte[] data = msg.encode();
-            byteBuffer.putShort(msg.getTypeCode());
-            byteBuffer.put(data);
-        }
-
-        byteBuffer.flip();
-        int length = byteBuffer.limit();
-        byte[] content = new byte[length + 4];
-        intToBytes(length, content, 0);
-        byteBuffer.get(content, 4, length);
-        if (msgs.size() > 20) {
-            if (LOGGER.isDebugEnabled()) {
-                LOGGER.debug("msg in one packet:" + msgs.size() + ",buffer size:" + content.length);
-            }
-        }
-        return content;
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        if (in.readableBytes() < 4) {
-            return false;
-        }
-
-        int length = in.readInt();
-        if (in.readableBytes() < length) {
-            return false;
-        }
-
-        byte[] buffer = new byte[length];
-        in.readBytes(buffer);
-        ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
-        doDecode(byteBuffer);
-        return true;
-    }
-
-    private void doDecode(ByteBuffer byteBuffer) {
-        short msgNum = byteBuffer.getShort();
-        for (int idx = 0; idx < msgNum; idx++) {
-            short typeCode = byteBuffer.getShort();
-            MergedMessage message = getMergeRequestInstanceByCode(typeCode);
-            message.decode(byteBuffer);
-            msgs.add((AbstractMessage)message);
-        }
+        return MessageType.TYPE_SEATA_MERGE;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/MessageType.java b/core/src/main/java/io/seata/core/protocol/MessageType.java
new file mode 100644
index 0000000000000000000000000000000000000000..b08593f5ba8b1e550b1785f7d8808855dabf694e
--- /dev/null
+++ b/core/src/main/java/io/seata/core/protocol/MessageType.java
@@ -0,0 +1,125 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.protocol;
+
+/**
+ * The type Message codec type.
+ *
+ * @author zhangsen
+ * @data 2019 /5/6
+ */
+public class MessageType {
+
+    /**
+     * The constant TYPE_GLOBAL_BEGIN.
+     */
+    public static final short TYPE_GLOBAL_BEGIN = 1;
+    /**
+     * The constant TYPE_GLOBAL_BEGIN_RESULT.
+     */
+    public static final short TYPE_GLOBAL_BEGIN_RESULT = 2;
+    /**
+     * The constant TYPE_GLOBAL_COMMIT.
+     */
+    public static final short TYPE_GLOBAL_COMMIT = 7;
+    /**
+     * The constant TYPE_GLOBAL_COMMIT_RESULT.
+     */
+    public static final short TYPE_GLOBAL_COMMIT_RESULT = 8;
+    /**
+     * The constant TYPE_GLOBAL_ROLLBACK.
+     */
+    public static final short TYPE_GLOBAL_ROLLBACK = 9;
+    /**
+     * The constant TYPE_GLOBAL_ROLLBACK_RESULT.
+     */
+    public static final short TYPE_GLOBAL_ROLLBACK_RESULT = 10;
+    /**
+     * The constant TYPE_GLOBAL_STATUS.
+     */
+    public static final short TYPE_GLOBAL_STATUS = 15;
+    /**
+     * The constant TYPE_GLOBAL_STATUS_RESULT.
+     */
+    public static final short TYPE_GLOBAL_STATUS_RESULT = 16;
+    /**
+     * The constant TYPE_GLOBAL_LOCK_QUERY.
+     */
+    public static final short TYPE_GLOBAL_LOCK_QUERY = 21;
+    /**
+     * The constant TYPE_GLOBAL_LOCK_QUERY_RESULT.
+     */
+    public static final short TYPE_GLOBAL_LOCK_QUERY_RESULT = 22;
+
+    /**
+     * The constant TYPE_BRANCH_COMMIT.
+     */
+    public static final short TYPE_BRANCH_COMMIT = 3;
+    /**
+     * The constant TYPE_BRANCH_COMMIT_RESULT.
+     */
+    public static final short TYPE_BRANCH_COMMIT_RESULT = 4;
+    /**
+     * The constant TYPE_BRANCH_ROLLBACK.
+     */
+    public static final short TYPE_BRANCH_ROLLBACK = 5;
+    /**
+     * The constant TYPE_BRANCH_ROLLBACK_RESULT.
+     */
+    public static final short TYPE_BRANCH_ROLLBACK_RESULT = 6;
+    /**
+     * The constant TYPE_BRANCH_REGISTER.
+     */
+    public static final short TYPE_BRANCH_REGISTER = 11;
+    /**
+     * The constant TYPE_BRANCH_REGISTER_RESULT.
+     */
+    public static final short TYPE_BRANCH_REGISTER_RESULT = 12;
+    /**
+     * The constant TYPE_BRANCH_STATUS_REPORT.
+     */
+    public static final short TYPE_BRANCH_STATUS_REPORT = 13;
+    /**
+     * The constant TYPE_BRANCH_STATUS_REPORT_RESULT.
+     */
+    public static final short TYPE_BRANCH_STATUS_REPORT_RESULT = 14;
+
+    /**
+     * The constant TYPE_SEATA_MERGE.
+     */
+    public static final short TYPE_SEATA_MERGE = 59;
+    /**
+     * The constant TYPE_SEATA_MERGE_RESULT.
+     */
+    public static final short TYPE_SEATA_MERGE_RESULT = 60;
+
+    /**
+     * The constant TYPE_REG_CLT.
+     */
+    public static final short TYPE_REG_CLT = 101;
+    /**
+     * The constant TYPE_REG_CLT_RESULT.
+     */
+    public static final short TYPE_REG_CLT_RESULT = 102;
+    /**
+     * The constant TYPE_REG_RM.
+     */
+    public static final short TYPE_REG_RM = 103;
+    /**
+     * The constant TYPE_REG_RM_RESULT.
+     */
+    public static final short TYPE_REG_RM_RESULT = 104;
+}
diff --git a/core/src/main/java/io/seata/core/protocol/MergedMessage.java b/core/src/main/java/io/seata/core/protocol/MessageTypeAware.java
similarity index 72%
rename from core/src/main/java/io/seata/core/protocol/MergedMessage.java
rename to core/src/main/java/io/seata/core/protocol/MessageTypeAware.java
index c8273ad5848e9c7d8d28aff9df68c0b847c97b58..80a9ab429a2a082de58b0a031cc6937da3819d5f 100644
--- a/core/src/main/java/io/seata/core/protocol/MergedMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/MessageTypeAware.java
@@ -15,19 +15,15 @@
  */
 package io.seata.core.protocol;
 
-import java.nio.ByteBuffer;
-
 /**
- * The interface Merged message.
- *
- * @author jimin.jm @alibaba-inc.com
- * @date 2018 /9/17
+ * @author zhangsen
  */
-public interface MergedMessage {
+public interface MessageTypeAware {
+
     /**
-     * Decode.
-     *
-     * @param byteBuffer the byte buffer
+     * return the message type
+     * @return
      */
-    void decode(ByteBuffer byteBuffer);
+    short getTypeCode();
+
 }
diff --git a/core/src/main/java/io/seata/core/protocol/ProtocolConstants.java b/core/src/main/java/io/seata/core/protocol/ProtocolConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bdba890bc524a5de29d62f49a7419765ea26496
--- /dev/null
+++ b/core/src/main/java/io/seata/core/protocol/ProtocolConstants.java
@@ -0,0 +1,89 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.protocol;
+
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.codec.CodecType;
+import io.seata.core.codec.CompressorType;
+import io.seata.core.constants.ConfigurationKeys;
+
+/**
+ * @author Geng Zhang
+ * @since 0.7.0
+ */
+public class ProtocolConstants {
+
+    /**
+     * Magic code
+     */
+    public static final byte[] MAGIC_CODE_BYTES = {(byte) 0xda, (byte) 0xda};
+
+    /**
+     * Protocol version
+     */
+    public static final byte VERSION = 1;
+
+    /**
+     * Max frame length
+     */
+    public static final int MAX_FRAME_LENGTH = 8 * 1024 * 1024;
+
+    /**
+     * HEAD_LENGTH of protocol v1
+     */
+    public static final int V1_HEAD_LENGTH = 16;
+    
+    /**
+     * Message type: Request
+     */
+    public static final byte MSGTYPE_RESQUEST = 0;
+    /**
+     * Message type: Response
+     */
+    public static final byte MSGTYPE_RESPONSE = 1;
+    /**
+     * Message type: Request which no need response
+     */
+    public static final byte MSGTYPE_RESQUEST_ONEWAY = 2;
+    /**
+     * Message type: Heartbeat Request
+     */
+    public static final byte MSGTYPE_HEARTBEAT_REQUEST = 3;
+    /**
+     * Message type: Heartbeat Response
+     */
+    public static final byte MSGTYPE_HEARTBEAT_RESPONSE = 4;
+
+    // public static final byte MSGTYPE_NEGOTIATOR_REQUEST = 5;
+    // public static final byte MSGTYPE_NEGOTIATOR_RESPONSE = 6;
+
+    /**
+     * Configured codec by user, default is SEATA
+     * 
+     * @see CodecType#SEATA
+     */
+    public static final byte CONFIGURED_CODEC = CodecType.getByName(ConfigurationFactory.getInstance()
+            .getConfig(ConfigurationKeys.SERIALIZE_FOR_RPC, CodecType.SEATA.name())).getCode();
+
+    /**
+     * Configured compressor by user, default is NONE
+     *
+     * @see CompressorType#NONE
+     */
+    public static final byte CONFIGURED_COMPRESSOR = CompressorType.getByName(ConfigurationFactory.getInstance()
+            .getConfig(ConfigurationKeys.COMPRESSOR_FOR_RPC, CompressorType.NONE.name())).getCode();
+
+}
diff --git a/core/src/main/java/io/seata/core/protocol/RegisterRMRequest.java b/core/src/main/java/io/seata/core/protocol/RegisterRMRequest.java
index b2ffda034d46b301103b3bf3ea867129604d24be..559c78588f9079e7f6d98754c492f06cb21759cc 100644
--- a/core/src/main/java/io/seata/core/protocol/RegisterRMRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/RegisterRMRequest.java
@@ -26,9 +26,6 @@ import io.netty.buffer.ByteBuf;
  * @date 2018 /10/10
  */
 public class RegisterRMRequest extends AbstractIdentifyRequest implements Serializable {
-    private static final long serialVersionUID = 7539732523682335742L;
-
-    private String resourceIds;
 
     /**
      * Instantiates a new Register rm request.
@@ -47,6 +44,8 @@ public class RegisterRMRequest extends AbstractIdentifyRequest implements Serial
         super(applicationId, transactionServiceGroup);
     }
 
+    private String resourceIds;
+
     /**
      * Gets resource ids.
      *
@@ -67,106 +66,15 @@ public class RegisterRMRequest extends AbstractIdentifyRequest implements Serial
 
     @Override
     public short getTypeCode() {
-        return TYPE_REG_RM;
-    }
-
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        if (this.resourceIds != null) {
-            byte[] bs = resourceIds.getBytes(UTF8);
-            byteBuffer.putInt(bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putInt(0);
-        }
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        short len = in.readShort();
-        if (len > 0) {
-            if (in.readableBytes() < len) {
-                return false;
-            }
-            byte[] bs = new byte[len];
-            in.readBytes(bs);
-            this.setVersion(new String(bs, UTF8));
-        } else {
-            return false;
-        }
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (len > 0) {
-            if (in.readableBytes() < len) {
-                return false;
-            }
-            byte[] bs = new byte[len];
-            in.readBytes(bs);
-            this.setApplicationId(new String(bs, UTF8));
-        }
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (in.readableBytes() < len) {
-            return false;
-        }
-        byte[] bs = new byte[len];
-        in.readBytes(bs);
-        this.setTransactionServiceGroup(new String(bs, UTF8));
-
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        len = in.readShort();
-
-        if (len > 0) {
-            if (in.readableBytes() < len) {
-                return false;
-            }
-            bs = new byte[len];
-            in.readBytes(bs);
-            this.setExtraData(new String(bs, UTF8));
-        }
-
-        int iLen;
-        if (in.readableBytes() < 4) {
-            return false;
-        }
-        iLen = in.readInt();
-
-        if (iLen > 0) {
-            if (in.readableBytes() < iLen) {
-                return false;
-            }
-            bs = new byte[iLen];
-            in.readBytes(bs);
-            this.setResourceIds(new String(bs, UTF8));
-            return true;
-        }
-        //maybe null
-
-        return true;
+        return MessageType.TYPE_REG_RM;
     }
 
     @Override
     public String toString() {
         return "RegisterRMRequest{" +
-            "resourceIds='" + resourceIds + '\'' +
-            ", applicationId='" + applicationId + '\'' +
-            ", transactionServiceGroup='" + transactionServiceGroup + '\'' +
-            '}';
+                "resourceIds='" + resourceIds + '\'' +
+                ", applicationId='" + applicationId + '\'' +
+                ", transactionServiceGroup='" + transactionServiceGroup + '\'' +
+                '}';
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/RegisterRMResponse.java b/core/src/main/java/io/seata/core/protocol/RegisterRMResponse.java
index 7082e7543e616c0f77eff92db0ea3adb34b04089..a03bd8dd5c01d4f4166e20f193e83f7d7717a0a4 100644
--- a/core/src/main/java/io/seata/core/protocol/RegisterRMResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/RegisterRMResponse.java
@@ -24,7 +24,6 @@ import java.io.Serializable;
  * @date 2018 /10/10
  */
 public class RegisterRMResponse extends AbstractIdentifyResponse implements Serializable {
-    private static final long serialVersionUID = 6391375605848221420L;
 
     /**
      * Instantiates a new Register rm response.
@@ -45,6 +44,6 @@ public class RegisterRMResponse extends AbstractIdentifyResponse implements Seri
 
     @Override
     public short getTypeCode() {
-        return TYPE_REG_RM_RESULT;
+        return MessageType.TYPE_REG_RM_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/RegisterTMRequest.java b/core/src/main/java/io/seata/core/protocol/RegisterTMRequest.java
index 116764253302be49a4573400c10ae9e8621c8bf8..aadaca77cf2713e3f41211b5ab33211c38a7eaa6 100644
--- a/core/src/main/java/io/seata/core/protocol/RegisterTMRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/RegisterTMRequest.java
@@ -57,7 +57,7 @@ public class RegisterTMRequest extends AbstractIdentifyRequest implements Serial
 
     @Override
     public short getTypeCode() {
-        return TYPE_REG_CLT;
+        return MessageType.TYPE_REG_CLT;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/RegisterTMResponse.java b/core/src/main/java/io/seata/core/protocol/RegisterTMResponse.java
index 50c32edc00248aa17afdfe04f351ecdbd08f3455..9ea88e5261aa952d05e956f0350140c216a1327e 100644
--- a/core/src/main/java/io/seata/core/protocol/RegisterTMResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/RegisterTMResponse.java
@@ -24,7 +24,6 @@ import java.io.Serializable;
  * @date 2018 /10/15
  */
 public class RegisterTMResponse extends AbstractIdentifyResponse implements Serializable {
-    private static final long serialVersionUID = 3629846050062228749L;
 
     /**
      * Instantiates a new Register tm response.
@@ -45,6 +44,6 @@ public class RegisterTMResponse extends AbstractIdentifyResponse implements Seri
 
     @Override
     public short getTypeCode() {
-        return TYPE_REG_CLT_RESULT;
+        return MessageType.TYPE_REG_CLT_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/ResultCode.java b/core/src/main/java/io/seata/core/protocol/ResultCode.java
index 215632f3179bf523cf0deba116c0e745f4e08c1f..aea5d09ae7f86bbe5e529580d3973f3b9b38a900 100644
--- a/core/src/main/java/io/seata/core/protocol/ResultCode.java
+++ b/core/src/main/java/io/seata/core/protocol/ResultCode.java
@@ -20,7 +20,7 @@ package io.seata.core.protocol;
  *
  * @author sharajava
  */
-public enum ResultCode {
+public enum  ResultCode {
 
     /**
      * Failed result code.
diff --git a/core/src/main/java/io/seata/core/protocol/RpcMessage.java b/core/src/main/java/io/seata/core/protocol/RpcMessage.java
index b4dc0aa9a50494209135c91018b161bf19861acb..10b27b0a99ce1abcff8d6321646d44fea113a912 100644
--- a/core/src/main/java/io/seata/core/protocol/RpcMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/RpcMessage.java
@@ -15,7 +15,8 @@
  */
 package io.seata.core.protocol;
 
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * The type Rpc message.
@@ -25,21 +26,11 @@ import java.util.concurrent.atomic.AtomicLong;
  */
 public class RpcMessage {
 
-    private static AtomicLong NEXT_ID = new AtomicLong(0);
-
-    /**
-     * Gets next message id.
-     *
-     * @return the next message id
-     */
-    public static long getNextMessageId() {
-        return NEXT_ID.incrementAndGet();
-    }
-
-    private long id;
-    private boolean isAsync;
-    private boolean isRequest;
-    private boolean isHeartbeat;
+    private int id;
+    private byte messageType;
+    private byte codec;
+    private byte compressor;
+    private Map<String, String> headMap = new ConcurrentHashMap<>();
     private Object body;
 
     /**
@@ -47,7 +38,7 @@ public class RpcMessage {
      *
      * @return the id
      */
-    public long getId() {
+    public int getId() {
         return id;
     }
 
@@ -56,79 +47,123 @@ public class RpcMessage {
      *
      * @param id the id
      */
-    public void setId(long id) {
+    public void setId(int id) {
         this.id = id;
     }
 
     /**
-     * Is async boolean.
+     * Gets body.
      *
-     * @return the boolean
+     * @return the body
      */
-    public boolean isAsync() {
-        return isAsync;
+    public Object getBody() {
+        return body;
     }
 
     /**
-     * Sets async.
+     * Sets body.
      *
-     * @param async the async
+     * @param body the body
      */
-    public void setAsync(boolean async) {
-        isAsync = async;
+    public void setBody(Object body) {
+        this.body = body;
     }
 
     /**
-     * Is request boolean.
+     * Gets codec.
      *
-     * @return the boolean
+     * @return the codec
      */
-    public boolean isRequest() {
-        return isRequest;
+    public byte getCodec() {
+        return codec;
     }
 
     /**
-     * Sets request.
+     * Sets codec.
      *
-     * @param request the request
+     * @param codec the codec
+     * @return the codec
      */
-    public void setRequest(boolean request) {
-        isRequest = request;
+    public RpcMessage setCodec(byte codec) {
+        this.codec = codec;
+        return this;
     }
 
     /**
-     * Is heartbeat boolean.
+     * Gets compressor.
      *
-     * @return the boolean
+     * @return the compressor
      */
-    public boolean isHeartbeat() {
-        return isHeartbeat;
+    public byte getCompressor() {
+        return compressor;
     }
 
     /**
-     * Sets heartbeat.
+     * Sets compressor.
      *
-     * @param heartbeat the heartbeat
+     * @param compressor the compressor
+     * @return the compressor
      */
-    public void setHeartbeat(boolean heartbeat) {
-        isHeartbeat = heartbeat;
+    public RpcMessage setCompressor(byte compressor) {
+        this.compressor = compressor;
+        return this;
     }
 
     /**
-     * Gets body.
+     * Gets head map.
      *
-     * @return the body
+     * @return the head map
      */
-    public Object getBody() {
-        return body;
+    public Map<String, String> getHeadMap() {
+        return headMap;
     }
 
     /**
-     * Sets body.
+     * Sets head map.
      *
-     * @param body the body
+     * @param headMap the head map
+     * @return the head map
      */
-    public void setBody(Object body) {
-        this.body = body;
+    public RpcMessage setHeadMap(Map<String, String> headMap) {
+        this.headMap = headMap;
+        return this;
+    }
+
+    /**
+     * Gets head.
+     *
+     * @param headKey the head key
+     * @return the head
+     */
+    public String getHead(String headKey) {
+        return headMap.get(headKey);
+    }
+
+    /**
+     * Put head.
+     *
+     * @param headKey   the head key
+     * @param headValue the head value
+     */
+    public void putHead(String headKey, String headValue) {
+        headMap.put(headKey, headValue);
+    }
+
+    /**
+     * Gets message type.
+     *
+     * @return the message type
+     */
+    public byte getMessageType() {
+        return messageType;
+    }
+
+    /**
+     * Sets message type.
+     *
+     * @param messageType the message type
+     */
+    public void setMessageType(byte messageType) {
+        this.messageType = messageType;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/Version.java b/core/src/main/java/io/seata/core/protocol/Version.java
index fe0be6e490113078003bf5a0925769f78a4d4b44..db9f85cc10f61fce2b4c5868f7e4f23ac74e6a9f 100644
--- a/core/src/main/java/io/seata/core/protocol/Version.java
+++ b/core/src/main/java/io/seata/core/protocol/Version.java
@@ -31,7 +31,7 @@ public class Version {
     /**
      * The constant CURRENT.
      */
-    public static final String CURRENT = "0.6.1";
+    public static final String CURRENT = "0.7.0";
 
     /**
      * The constant VERSION_MAP.
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndRequest.java
index a6d0fa72708350c806b5f35f14d50be748a48833..b918f7361843f39459d67c6f2fed6a8aae8a179b 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndRequest.java
@@ -17,7 +17,6 @@ package io.seata.core.protocol.transaction;
 
 import java.nio.ByteBuffer;
 
-import io.netty.buffer.ByteBuf;
 import io.seata.core.model.BranchType;
 
 /**
@@ -27,8 +26,6 @@ import io.seata.core.model.BranchType;
  */
 public abstract class AbstractBranchEndRequest extends AbstractTransactionRequestToRM {
 
-    private static final long serialVersionUID = 5083828939317068713L;
-
     /**
      * The Xid.
      */
@@ -144,118 +141,6 @@ public abstract class AbstractBranchEndRequest extends AbstractTransactionReques
         this.applicationData = applicationData;
     }
 
-    @Override
-    public byte[] encode() {
-        byte[] applicationDataBytes = null;
-        if (this.applicationData != null) {
-            applicationDataBytes = applicationData.getBytes(UTF8);
-            if (applicationDataBytes.length > 512) {
-                byteBuffer = ByteBuffer.allocate(applicationDataBytes.length + 1024);
-            }
-        }
-
-        // 1. xid
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-        // 2. Branch Id
-        byteBuffer.putLong(this.branchId);
-        // 3. Branch Type
-        byteBuffer.put((byte)this.branchType.ordinal());
-        // 4. Resource Id
-        if (this.resourceId != null) {
-            byte[] bs = resourceId.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        // 5. Application Data
-        if (this.applicationData != null) {
-            byteBuffer.putInt(applicationDataBytes.length);
-            if (applicationDataBytes.length > 0) {
-                byteBuffer.put(applicationDataBytes);
-            }
-        } else {
-            byteBuffer.putInt(0);
-        }
-
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        return content;
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        int xidLen = 0;
-        if (in.readableBytes() >= 2) {
-            xidLen = in.readShort();
-        }
-        if (xidLen <= 0) {
-            return false;
-        }
-        if (in.readableBytes() < xidLen) {
-            return false;
-        }
-        byte[] bs = new byte[xidLen];
-        in.readBytes(bs);
-        setXid(new String(bs, UTF8));
-
-        if (in.readableBytes() < 8) {
-            return false;
-        }
-        this.branchId = in.readLong();
-
-        if (in.readableBytes() < 1) {
-            return false;
-        }
-        this.branchType = BranchType.get(in.readByte());
-
-        int resourceIdLen = 0;
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        resourceIdLen = in.readShort();
-
-        if (resourceIdLen <= 0) {
-            return false;
-        }
-        if (in.readableBytes() < resourceIdLen) {
-            return false;
-        }
-        bs = new byte[resourceIdLen];
-        in.readBytes(bs);
-        setResourceId(new String(bs, UTF8));
-
-        int applicationDataLen = 0;
-        if (in.readableBytes() < 4) {
-            return false;
-        }
-        applicationDataLen = in.readInt();
-
-        if (applicationDataLen > 0) {
-            if (in.readableBytes() < applicationDataLen) {
-                return false;
-            }
-            bs = new byte[applicationDataLen];
-            in.readBytes(bs);
-            setApplicationData(new String(bs, UTF8));
-        } else {
-            //application data may be null
-        }
-        return true;
-    }
-
     @Override
     public String toString() {
         StringBuilder result = new StringBuilder();
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndResponse.java
index 6aafd9e54a00bd1b91e6f08f0c152d3c63b21ae2..5d3b03743f968a5719065b33f57e51201b1eb747 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractBranchEndResponse.java
@@ -15,9 +15,6 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
-import io.netty.buffer.ByteBuf;
 import io.seata.core.model.BranchStatus;
 
 /**
@@ -95,63 +92,6 @@ public abstract class AbstractBranchEndResponse extends AbstractTransactionRespo
         this.branchStatus = branchStatus;
     }
 
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-        byteBuffer.putLong(this.branchId);
-        byteBuffer.put((byte)branchStatus.getCode());
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-        short xidLen = byteBuffer.getShort();
-        if (xidLen > 0) {
-            byte[] bs = new byte[xidLen];
-            byteBuffer.get(bs);
-            this.setXid(new String(bs, UTF8));
-        }
-        branchId = byteBuffer.getLong();
-        branchStatus = BranchStatus.get(byteBuffer.get());
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        boolean s = super.decode(in);
-        if (!s) {
-            return s;
-        }
-        short xidLen;
-        if (in.readableBytes() < 2) {
-            return false;
-        }
-        xidLen = in.readShort();
-        if (in.readableBytes() < xidLen) {
-            return false;
-        }
-        byte[] bs = new byte[xidLen];
-        in.readBytes(bs);
-        this.setXid(new String(bs, UTF8));
-        if (in.readableBytes() < 8) {
-            return false;
-        }
-        branchId = in.readLong();
-        if (in.readableBytes() < 1) {
-            return false;
-        }
-        branchStatus = BranchStatus.get(in.readByte());
-        return true;
-    }
-
     @Override
     public String toString() {
         StringBuilder result = new StringBuilder();
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndRequest.java
index b77a111e50110e6e90aaa695552a8fb2d0467861..85a8a09ed2571688636736f8ba784fa685a64c00 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndRequest.java
@@ -15,16 +15,12 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
-import io.seata.core.protocol.MergedMessage;
-
 /**
  * The type Abstract global end request.
  *
  * @author sharajava
  */
-public abstract class AbstractGlobalEndRequest extends AbstractTransactionRequestToTC implements MergedMessage {
+public abstract class AbstractGlobalEndRequest extends AbstractTransactionRequestToTC {
 
     private String xid;
 
@@ -69,51 +65,6 @@ public abstract class AbstractGlobalEndRequest extends AbstractTransactionReques
         this.extraData = extraData;
     }
 
-    @Override
-    public byte[] encode() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(256);
-        // 1. xid
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-        if (this.extraData != null) {
-            byte[] bs = extraData.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        return content;
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        short xidLen = byteBuffer.getShort();
-        if (xidLen > 0) {
-            byte[] bs = new byte[xidLen];
-            byteBuffer.get(bs);
-            this.setXid(new String(bs, UTF8));
-        }
-        short len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            this.setExtraData(new String(bs, UTF8));
-        }
-    }
-
     @Override
     public String toString() {
         StringBuilder result = new StringBuilder();
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndResponse.java
index f3e0825b1e477c2bfbdfda2a1f73351f53a15e8a..cd6ac513faf9f00a8f0ecb0a9c19c8930633656b 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractGlobalEndResponse.java
@@ -15,7 +15,6 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
 
 import io.seata.core.model.GlobalStatus;
 
@@ -49,18 +48,6 @@ public abstract class AbstractGlobalEndResponse extends AbstractTransactionRespo
         this.globalStatus = globalStatus;
     }
 
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        byteBuffer.put((byte)globalStatus.getCode());
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-        globalStatus = GlobalStatus.get(byteBuffer.get());
-    }
-
     @Override
     public String toString() {
         StringBuilder result = new StringBuilder();
@@ -75,4 +62,5 @@ public abstract class AbstractGlobalEndResponse extends AbstractTransactionRespo
 
         return result.toString();
     }
+
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequest.java
index 399b7492c7b448d4a48bdc4bc357823265204d4f..f996f2a2f78552a737b8bb08f2809635a835e161 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequest.java
@@ -15,7 +15,6 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
 
 import io.seata.core.protocol.AbstractMessage;
 import io.seata.core.rpc.RpcContext;
@@ -27,11 +26,6 @@ import io.seata.core.rpc.RpcContext;
  */
 public abstract class AbstractTransactionRequest extends AbstractMessage {
 
-    /**
-     * The Byte buffer.
-     */
-    protected ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
-
     /**
      * Handle abstract transaction response.
      *
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToRM.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToRM.java
index b22b3b28d003aafd8eaa495169058ccc7078b668..cab10150900e4c1c25924ef7d8dbd96f32dbb7ad 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToRM.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToRM.java
@@ -15,7 +15,6 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
 
 /**
  * The type Abstract transaction request to rm.
@@ -24,11 +23,6 @@ import java.nio.ByteBuffer;
  */
 public abstract class AbstractTransactionRequestToRM extends AbstractTransactionRequest {
 
-    /**
-     * The Byte buffer.
-     */
-    protected ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
-
     /**
      * The Handler.
      */
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToTC.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToTC.java
index b24abfa0ac9cedee97d8900634475f0962e60e60..21d8435af526088226c057b6da767369855acd89 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToTC.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionRequestToTC.java
@@ -15,7 +15,6 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
 
 /**
  * The type Abstract transaction request to tc.
@@ -24,11 +23,6 @@ import java.nio.ByteBuffer;
  */
 public abstract class AbstractTransactionRequestToTC extends AbstractTransactionRequest {
 
-    /**
-     * The Byte buffer.
-     */
-    protected ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
-
     /**
      * The Handler.
      */
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionResponse.java
index 8bfe35257194742372b67d5f9ac9282a4dc0f52a..e7d3b1f3feb2c36cba1174e31dcfa375ae7ffe12 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/AbstractTransactionResponse.java
@@ -15,9 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
 
-import io.netty.buffer.ByteBuf;
 import io.seata.core.exception.TransactionExceptionCode;
 import io.seata.core.protocol.AbstractResultMessage;
 
@@ -48,25 +46,4 @@ public abstract class AbstractTransactionResponse extends AbstractResultMessage
         this.transactionExceptionCode = transactionExceptionCode;
     }
 
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        byteBuffer.put((byte)transactionExceptionCode.ordinal());
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-        transactionExceptionCode = TransactionExceptionCode.get(byteBuffer.get());
-    }
-
-    @Override
-    public boolean decode(ByteBuf in) {
-        boolean s = super.decode(in);
-        if (!s) {
-            return s;
-        }
-        transactionExceptionCode = TransactionExceptionCode.get(in.readByte());
-        return true;
-    }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitRequest.java
index 29368392b6fe0d9e88ec19ee4bdb7da0e27405c0..39f05f717b861158d3b3affd34e85fa2b3e0f3b0 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitRequest.java
@@ -15,8 +15,10 @@
  */
 package io.seata.core.protocol.transaction;
 
-import io.seata.core.protocol.AbstractMessage;
+import io.seata.common.util.StringUtils;
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
+import io.seata.core.protocol.AbstractMessage;
 
 /**
  * The type Branch commit request.
@@ -27,11 +29,13 @@ public class BranchCommitRequest extends AbstractBranchEndRequest {
 
     @Override
     public short getTypeCode() {
-        return AbstractMessage.TYPE_BRANCH_COMMIT;
+        return MessageType.TYPE_BRANCH_COMMIT;
     }
 
     @Override
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
         return handler.handle(this);
     }
+
+
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitResponse.java
index a4e4be291bdb903dd878ff2784da1036744fb1ef..6788373a7cc8f24e00765aa4192a16d4ab4cb0d4 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchCommitResponse.java
@@ -15,7 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
-import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MessageType;
 
 /**
  * The type Branch commit response.
@@ -26,6 +26,6 @@ public class BranchCommitResponse extends AbstractBranchEndResponse {
 
     @Override
     public short getTypeCode() {
-        return AbstractMessage.TYPE_BRANCH_COMMIT_RESULT;
+        return MessageType.TYPE_BRANCH_COMMIT_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterRequest.java
index e58c20ba6a2cbc9519e439204534b28d426b68e5..4f7155a717e2294a16b629e4e7b8a3df918cbe6e 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterRequest.java
@@ -15,10 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import io.seata.core.model.BranchType;
-import io.seata.core.protocol.MergedMessage;
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -26,9 +24,7 @@ import io.seata.core.rpc.RpcContext;
  *
  * @author sharajava
  */
-public class BranchRegisterRequest extends AbstractTransactionRequestToTC implements MergedMessage {
-
-    private static final long serialVersionUID = 1242711598812634704L;
+public class BranchRegisterRequest extends AbstractTransactionRequestToTC  {
 
     private String xid;
 
@@ -114,7 +110,7 @@ public class BranchRegisterRequest extends AbstractTransactionRequestToTC implem
 
     @Override
     public short getTypeCode() {
-        return TYPE_BRANCH_REGISTER;
+        return MessageType.TYPE_BRANCH_REGISTER;
     }
 
     /**
@@ -135,105 +131,6 @@ public class BranchRegisterRequest extends AbstractTransactionRequestToTC implem
         this.applicationData = applicationData;
     }
 
-    @Override
-    public byte[] encode() {
-        int byteLenth = 0;
-        byte[] lockKeyBytes = null;
-        if (this.lockKey != null) {
-            lockKeyBytes = lockKey.getBytes(UTF8);
-            if (lockKeyBytes.length > 512) {
-                byteLenth += lockKeyBytes.length;
-            }
-        }
-        byte[] applicationDataBytes = null;
-        if (this.applicationData != null) {
-            applicationDataBytes = applicationData.getBytes(UTF8);
-            if (applicationDataBytes.length > 512) {
-                byteLenth += applicationDataBytes.length;
-            }
-        }
-        byteBuffer = ByteBuffer.allocate(byteLenth + 1024);
-
-        // 1. xid
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-        // 2. Branch Type
-        byteBuffer.put((byte)this.branchType.ordinal());
-        // 3. Resource Id
-        if (this.resourceId != null) {
-            byte[] bs = resourceId.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        // 4. Lock Key
-        if (this.lockKey != null) {
-            byteBuffer.putInt(lockKeyBytes.length);
-            if (lockKeyBytes.length > 0) {
-                byteBuffer.put(lockKeyBytes);
-            }
-        } else {
-            byteBuffer.putInt(0);
-        }
-
-        //5. applicationData
-        if (this.applicationData != null) {
-            byteBuffer.putInt(applicationDataBytes.length);
-            if (applicationDataBytes.length > 0) {
-                byteBuffer.put(applicationDataBytes);
-            }
-        } else {
-            byteBuffer.putInt(0);
-        }
-
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        return content;
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        short xidLen = byteBuffer.getShort();
-        if (xidLen > 0) {
-            byte[] bs = new byte[xidLen];
-            byteBuffer.get(bs);
-            this.setXid(new String(bs, UTF8));
-        }
-        this.branchType = BranchType.get(byteBuffer.get());
-        short len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            this.setResourceId(new String(bs, UTF8));
-        }
-
-        int iLen = byteBuffer.getInt();
-        if (iLen > 0) {
-            byte[] bs = new byte[iLen];
-            byteBuffer.get(bs);
-            this.setLockKey(new String(bs, UTF8));
-        }
-
-        int applicationDataLen = byteBuffer.getInt();
-        if (applicationDataLen > 0) {
-            byte[] bs = new byte[applicationDataLen];
-            byteBuffer.get(bs);
-            setApplicationData(new String(bs, UTF8));
-        }
-    }
-
     @Override
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
         return handler.handle(this, rpcContext);
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterResponse.java
index e5f2734c92fc63dbf7bbabc571b3be873848e939..b3420248cc5d7e2eb50428d9c6aa0aa481496467 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchRegisterResponse.java
@@ -16,9 +16,8 @@
 package io.seata.core.protocol.transaction;
 
 import java.io.Serializable;
-import java.nio.ByteBuffer;
 
-import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MessageType;
 
 /**
  * The type Branch register response.
@@ -27,7 +26,6 @@ import io.seata.core.protocol.AbstractMessage;
  */
 public class BranchRegisterResponse extends AbstractTransactionResponse implements Serializable {
 
-    private static final long serialVersionUID = 8317040433102745774L;
     private long branchId;
 
     /**
@@ -50,20 +48,7 @@ public class BranchRegisterResponse extends AbstractTransactionResponse implemen
 
     @Override
     public short getTypeCode() {
-        return AbstractMessage.TYPE_BRANCH_REGISTER_RESULT;
-    }
-
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        byteBuffer.putLong(branchId);
-
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-        this.branchId = byteBuffer.getLong();
+        return MessageType.TYPE_BRANCH_REGISTER_RESULT;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchReportRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchReportRequest.java
index 8bc0a02dc6fdc48e2fa8df7f9d5cb8a6e88d3394..d16628c12f0201c842850a8d56cf496066519120 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchReportRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchReportRequest.java
@@ -15,19 +15,17 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
 import io.seata.core.model.BranchStatus;
 import io.seata.core.model.BranchType;
-import io.seata.core.protocol.MergedMessage;
 import io.seata.core.rpc.RpcContext;
+import io.seata.core.protocol.MessageType;
 
 /**
  * The type Branch report request.
  *
  * @author jimin.jm @alibaba-inc.com
  */
-public class BranchReportRequest extends AbstractTransactionRequestToTC implements MergedMessage {
+public class BranchReportRequest extends AbstractTransactionRequestToTC {
 
     private String xid;
 
@@ -151,87 +149,9 @@ public class BranchReportRequest extends AbstractTransactionRequestToTC implemen
 
     @Override
     public short getTypeCode() {
-        return TYPE_BRANCH_STATUS_REPORT;
-    }
-
-    @Override
-    public byte[] encode() {
-        byte[] applicationDataBytes = null;
-        if (this.applicationData != null) {
-            applicationDataBytes = applicationData.getBytes(UTF8);
-            if (applicationDataBytes.length > 512) {
-                byteBuffer = ByteBuffer.allocate(applicationDataBytes.length + 1024);
-            }
-        }
-
-        // 1. xid
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-        // 2. Branch Id
-        byteBuffer.putLong(this.branchId);
-        // 3. Branch Status
-        byteBuffer.put((byte)this.status.getCode());
-        // 4. Resource Id
-        if (this.resourceId != null) {
-            byte[] bs = resourceId.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        // 5. Application Data
-        if (this.applicationData != null) {
-            byteBuffer.putInt(applicationDataBytes.length);
-            if (applicationDataBytes.length > 0) {
-                byteBuffer.put(applicationDataBytes);
-            }
-        } else {
-            byteBuffer.putInt(0);
-        }
-        //6. branchType
-        byteBuffer.put((byte) this.branchType.ordinal());
-
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        return content;
+        return MessageType.TYPE_BRANCH_STATUS_REPORT;
     }
 
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        short xidLen = byteBuffer.getShort();
-        if (xidLen > 0) {
-            byte[] bs = new byte[xidLen];
-            byteBuffer.get(bs);
-            this.setXid(new String(bs, UTF8));
-        }
-        this.branchId = byteBuffer.getLong();
-        this.status = BranchStatus.get(byteBuffer.get());
-        short len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            this.resourceId = new String(bs, UTF8);
-        }
-
-        int iLen = byteBuffer.getInt();
-        if (iLen > 0) {
-            byte[] bs = new byte[iLen];
-            byteBuffer.get(bs);
-            this.applicationData = new String(bs, UTF8);
-        }
-        this.branchType = BranchType.get(byteBuffer.get());
-    }
 
     @Override
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchReportResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchReportResponse.java
index d2a744d0205617c4f99966db8d8611592d3f00c5..05794718c3fa012995cf2d82507fe7d5047b6b90 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchReportResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchReportResponse.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
+
 /**
  * The type Branch report response.
  *
@@ -24,6 +26,6 @@ public class BranchReportResponse extends AbstractTransactionResponse {
 
     @Override
     public short getTypeCode() {
-        return TYPE_BRANCH_STATUS_REPORT_RESULT;
+        return MessageType.TYPE_BRANCH_STATUS_REPORT_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackRequest.java
index e8a95cfb4dfa91e63fdfea6f14b372c0b7f1e81f..9a27bee9f5ef05406a024772fb58d3a2397b7104 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackRequest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -26,7 +27,7 @@ public class BranchRollbackRequest extends AbstractBranchEndRequest {
 
     @Override
     public short getTypeCode() {
-        return TYPE_BRANCH_ROLLBACK;
+        return MessageType.TYPE_BRANCH_ROLLBACK;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackResponse.java
index c9289a0a0d2719dde26c6c8ffd1908f8cec2bda0..b57e7fc40610f494843efe10d9c377c00497f70e 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/BranchRollbackResponse.java
@@ -15,7 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
-import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MessageType;
 
 /**
  * The type Branch rollback response.
@@ -26,6 +26,6 @@ public class BranchRollbackResponse extends AbstractBranchEndResponse {
 
     @Override
     public short getTypeCode() {
-        return AbstractMessage.TYPE_BRANCH_ROLLBACK_RESULT;
+        return MessageType.TYPE_BRANCH_ROLLBACK_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginRequest.java
index 2fef4d5218d0029c355f1c2b8d07b868e30aea03..2f0ca3659c81f3a14e95cb6dc48d3aacafac2f18 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginRequest.java
@@ -15,19 +15,16 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
-import io.seata.core.protocol.MergedMessage;
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
+import java.nio.ByteBuffer;
 
 /**
  * The type Global begin request.
  *
  * @author jimin.jm @alibaba-inc.com
  */
-public class GlobalBeginRequest extends AbstractTransactionRequestToTC implements MergedMessage {
-
-    private static final long serialVersionUID = 7236162274218388376L;
+public class GlobalBeginRequest extends AbstractTransactionRequestToTC {
 
     private int timeout = 60000;
 
@@ -71,41 +68,9 @@ public class GlobalBeginRequest extends AbstractTransactionRequestToTC implement
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_BEGIN;
-    }
-
-    @Override
-    public byte[] encode() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(256);
-        byteBuffer.putInt(timeout);
-
-        if (this.transactionName != null) {
-            byte[] bs = transactionName.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        byteBuffer.flip();
-        byte[] content = new byte[byteBuffer.limit()];
-        byteBuffer.get(content);
-        return content;
+        return MessageType.TYPE_GLOBAL_BEGIN;
     }
 
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        this.timeout = byteBuffer.getInt();
-
-        short len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            this.setTransactionName(new String(bs, UTF8));
-        }
-    }
 
     @Override
     public AbstractTransactionResponse handle(RpcContext rpcContext) {
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginResponse.java
index f92823c334e894ef796270794208361b8805efae..e6239e96112d0165db1dad2dee0fb7f98685e267 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalBeginResponse.java
@@ -15,9 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
-
-import io.seata.core.protocol.AbstractMessage;
+import io.seata.core.protocol.MessageType;
 
 /**
  * The type Global begin response.
@@ -26,8 +24,6 @@ import io.seata.core.protocol.AbstractMessage;
  */
 public class GlobalBeginResponse extends AbstractTransactionResponse {
 
-    private static final long serialVersionUID = -5947172130577163908L;
-
     private String xid;
 
     private String extraData;
@@ -70,50 +66,7 @@ public class GlobalBeginResponse extends AbstractTransactionResponse {
 
     @Override
     public short getTypeCode() {
-        return AbstractMessage.TYPE_GLOBAL_BEGIN_RESULT;
+        return MessageType.TYPE_GLOBAL_BEGIN_RESULT;
     }
 
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-
-        if (this.xid != null) {
-            byte[] bs = xid.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-
-        if (this.extraData != null) {
-            byte[] bs = extraData.getBytes(UTF8);
-            byteBuffer.putShort((short)bs.length);
-            if (bs.length > 0) {
-                byteBuffer.put(bs);
-            }
-        } else {
-            byteBuffer.putShort((short)0);
-        }
-    }
-
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-
-        short len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            setXid(new String(bs, UTF8));
-        }
-
-        len = byteBuffer.getShort();
-        if (len > 0) {
-            byte[] bs = new byte[len];
-            byteBuffer.get(bs);
-            setExtraData(new String(bs, UTF8));
-        }
-    }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitRequest.java
index bcf76379e06e01a3dc986904b9f6987226040ccd..645ca242de8e4f35c4672b13e0d96bf96cad7e82 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitRequest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -25,7 +26,7 @@ import io.seata.core.rpc.RpcContext;
 public class GlobalCommitRequest extends AbstractGlobalEndRequest {
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_COMMIT;
+        return MessageType.TYPE_GLOBAL_COMMIT;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitResponse.java
index e18084863f7409cbb2162b86309431a7cd4595cb..a88d87cb9ce9d9c161d01a3c5a5e6f82f50a033b 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalCommitResponse.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
+
 /**
  * The type Global commit response.
  *
@@ -24,6 +26,6 @@ public class GlobalCommitResponse extends AbstractGlobalEndResponse {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_COMMIT_RESULT;
+        return MessageType.TYPE_GLOBAL_COMMIT_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryRequest.java
index 048778f2dc5f1f37b326493d8cde0116db103de1..1c5e9f31369242f8b36cc0b893e827075fc33cc6 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryRequest.java
@@ -15,7 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
-import io.seata.core.protocol.MergedMessage;
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -23,11 +23,11 @@ import io.seata.core.rpc.RpcContext;
  *
  * @author jimin.jm @alibaba-inc.com
  */
-public class GlobalLockQueryRequest extends BranchRegisterRequest implements MergedMessage {
+public class GlobalLockQueryRequest extends BranchRegisterRequest  {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_LOCK_QUERY;
+        return MessageType.TYPE_GLOBAL_LOCK_QUERY;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryResponse.java
index ff8a4e9d8270f6d3b6516f6c63012f4b3abc73fe..63f421b016ba9fc52e24d0b60a03f3ce6509b1e8 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalLockQueryResponse.java
@@ -15,7 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
-import java.nio.ByteBuffer;
+import io.seata.core.protocol.MessageType;
+
 
 /**
  * The type Global lock query response.
@@ -46,18 +47,7 @@ public class GlobalLockQueryResponse extends AbstractTransactionResponse {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_LOCK_QUERY_RESULT;
-    }
-
-    @Override
-    protected void doEncode() {
-        super.doEncode();
-        byteBuffer.putShort((short)(lockable ? 1 : 0));
+        return MessageType.TYPE_GLOBAL_LOCK_QUERY_RESULT;
     }
 
-    @Override
-    public void decode(ByteBuffer byteBuffer) {
-        super.decode(byteBuffer);
-        this.lockable = byteBuffer.getShort() == 1;
-    }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackRequest.java
index 50bb00a5b0277dc40dccb79b3fdb6f534562347c..54eb6778e081911886eaaaddcb7a1c2b34093d34 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackRequest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -25,7 +26,7 @@ import io.seata.core.rpc.RpcContext;
 public class GlobalRollbackRequest extends AbstractGlobalEndRequest {
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_ROLLBACK;
+        return MessageType.TYPE_GLOBAL_ROLLBACK;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackResponse.java
index 7ab13fe3d4e37352369a2e30d30bf160d148b52f..8c17809c39b481d8224127689de98c12c730047b 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalRollbackResponse.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
+
 /**
  * The type Global rollback response.
  *
@@ -24,6 +26,6 @@ public class GlobalRollbackResponse extends AbstractGlobalEndResponse {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_ROLLBACK_RESULT;
+        return MessageType.TYPE_GLOBAL_ROLLBACK_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusRequest.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusRequest.java
index ec1aff8ab75cc879af24ff9ca61da05768630f79..3ec9979c0e75f5456431fe80347b344ea7532cb2 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusRequest.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusRequest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
 import io.seata.core.rpc.RpcContext;
 
 /**
@@ -26,7 +27,7 @@ public class GlobalStatusRequest extends AbstractGlobalEndRequest {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_STATUS;
+        return MessageType.TYPE_GLOBAL_STATUS;
     }
 
     @Override
diff --git a/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusResponse.java b/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusResponse.java
index a8e730a87cfdda983c143a28f72c3d7322351d7f..b12710625b99cc89dfa98766c3ed7dbb836be675 100644
--- a/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusResponse.java
+++ b/core/src/main/java/io/seata/core/protocol/transaction/GlobalStatusResponse.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
+
 /**
  * The type Global status response.
  *
@@ -24,6 +26,6 @@ public class GlobalStatusResponse extends AbstractGlobalEndResponse {
 
     @Override
     public short getTypeCode() {
-        return TYPE_GLOBAL_STATUS_RESULT;
+        return MessageType.TYPE_GLOBAL_STATUS_RESULT;
     }
 }
diff --git a/core/src/main/java/io/seata/core/rpc/ClientMessageListener.java b/core/src/main/java/io/seata/core/rpc/ClientMessageListener.java
index 0a34a71ee3cc0790eb5e150d101c12b3dbcb3da6..6d1a0e70b2cc0758d7fa28a4ca5c38908c063a12 100644
--- a/core/src/main/java/io/seata/core/rpc/ClientMessageListener.java
+++ b/core/src/main/java/io/seata/core/rpc/ClientMessageListener.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.rpc;
 
+import io.seata.core.protocol.RpcMessage;
+
 /**
  * The interface Client message listener.
  *
@@ -25,10 +27,9 @@ public interface ClientMessageListener {
     /**
      * On message.
      *
-     * @param msgId         the msg id
+     * @param request       the msg id
      * @param serverAddress the server address
-     * @param msg           the msg
      * @param sender        the sender
      */
-    void onMessage(long msgId, String serverAddress, Object msg, ClientMessageSender sender);
+    void onMessage(RpcMessage request, String serverAddress, ClientMessageSender sender);
 }
diff --git a/core/src/main/java/io/seata/core/rpc/ClientMessageSender.java b/core/src/main/java/io/seata/core/rpc/ClientMessageSender.java
index 8cfbf488b6156a0901b6d88952ddac741ebfd601..8804ba534c38c649ba0eb8818c5be0386c2cef78 100644
--- a/core/src/main/java/io/seata/core/rpc/ClientMessageSender.java
+++ b/core/src/main/java/io/seata/core/rpc/ClientMessageSender.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.rpc;
 
+import io.seata.core.protocol.RpcMessage;
+
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -57,9 +59,9 @@ public interface ClientMessageSender {
     /**
      * Send response.
      *
-     * @param msgId         the msg id
+     * @param request       the msg id
      * @param serverAddress the server address
      * @param msg           the msg
      */
-    void sendResponse(long msgId, String serverAddress, Object msg);
+    void sendResponse(RpcMessage request, String serverAddress, Object msg);
 }
diff --git a/core/src/main/java/io/seata/core/rpc/DefaultServerMessageListenerImpl.java b/core/src/main/java/io/seata/core/rpc/DefaultServerMessageListenerImpl.java
index aca924d21a7211f04810f695e5a11e983b3a19a3..5aed348bd5e7d389eb53cb341fdaa3cc4b2587db 100644
--- a/core/src/main/java/io/seata/core/rpc/DefaultServerMessageListenerImpl.java
+++ b/core/src/main/java/io/seata/core/rpc/DefaultServerMessageListenerImpl.java
@@ -32,6 +32,7 @@ import io.seata.core.protocol.RegisterRMRequest;
 import io.seata.core.protocol.RegisterRMResponse;
 import io.seata.core.protocol.RegisterTMRequest;
 import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.protocol.RpcMessage;
 import io.seata.core.protocol.Version;
 import io.seata.core.rpc.netty.RegisterCheckAuthHandler;
 
@@ -66,7 +67,8 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
     }
 
     @Override
-    public void onTrxMessage(long msgId, ChannelHandlerContext ctx, Object message, ServerMessageSender sender) {
+    public void onTrxMessage(RpcMessage request, ChannelHandlerContext ctx, ServerMessageSender sender) {
+        Object message = request.getBody();
         RpcContext rpcContext = ChannelManager.getContextFromIdentified(ctx.channel());
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug(
@@ -86,16 +88,16 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
             }
             MergeResultMessage resultMessage = new MergeResultMessage();
             resultMessage.setMsgs(results);
-            sender.sendResponse(msgId, ctx.channel(), resultMessage);
+            sender.sendResponse(request, ctx.channel(), resultMessage);
         } else if (message instanceof AbstractResultMessage) {
             transactionMessageHandler.onResponse((AbstractResultMessage)message, rpcContext);
         }
     }
 
     @Override
-    public void onRegRmMessage(long msgId, ChannelHandlerContext ctx, RegisterRMRequest message,
+    public void onRegRmMessage(RpcMessage request, ChannelHandlerContext ctx,
                                ServerMessageSender sender, RegisterCheckAuthHandler checkAuthHandler) {
-
+        RegisterRMRequest message = (RegisterRMRequest) request.getBody();
         boolean isSuccess = false;
         try {
             if (null == checkAuthHandler || checkAuthHandler.regResourceManagerCheckAuth(message)) {
@@ -107,15 +109,16 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
             isSuccess = false;
             LOGGER.error(exx.getMessage());
         }
-        sender.sendResponse(msgId, ctx.channel(), new RegisterRMResponse(isSuccess));
+        sender.sendResponse(request, ctx.channel(), new RegisterRMResponse(isSuccess));
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("rm register success,message:" + message + ",channel:" + ctx.channel());
         }
     }
 
     @Override
-    public void onRegTmMessage(long msgId, ChannelHandlerContext ctx, RegisterTMRequest message,
+    public void onRegTmMessage(RpcMessage request, ChannelHandlerContext ctx,
                                ServerMessageSender sender, RegisterCheckAuthHandler checkAuthHandler) {
+        RegisterTMRequest message = (RegisterTMRequest) request.getBody();
         String ipAndPort = NetUtil.toStringAddress(ctx.channel().remoteAddress());
         Version.putChannelVersion(ctx.channel(), message.getVersion());
         boolean isSuccess = false;
@@ -134,14 +137,15 @@ public class DefaultServerMessageListenerImpl implements ServerMessageListener {
             isSuccess = false;
             LOGGER.error(exx.getMessage());
         }
-        sender.sendResponse(msgId, ctx.channel(),
+        //FIXME please add success or fail
+        sender.sendResponse(request, ctx.channel(),
             new RegisterTMResponse(isSuccess));
     }
 
     @Override
-    public void onCheckMessage(long msgId, ChannelHandlerContext ctx, ServerMessageSender sender) {
+    public void onCheckMessage(RpcMessage request, ChannelHandlerContext ctx, ServerMessageSender sender) {
         try {
-            sender.sendResponse(msgId, ctx.channel(), HeartbeatMessage.PONG);
+            sender.sendResponse(request, ctx.channel(), HeartbeatMessage.PONG);
         } catch (Throwable throwable) {
             LOGGER.error("", "send response error", throwable);
         }
diff --git a/core/src/main/java/io/seata/core/rpc/RemotingClient.java b/core/src/main/java/io/seata/core/rpc/RemotingClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d44c16cb3e4acc709d4c4abeb0c74fbe4d266c8
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/RemotingClient.java
@@ -0,0 +1,24 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc;
+
+/**
+ * The interface remoting client.
+ *
+ * @author zhaojun
+ */
+public interface RemotingClient extends RemotingService {
+}
diff --git a/core/src/main/java/io/seata/core/rpc/ServerMessageListener.java b/core/src/main/java/io/seata/core/rpc/ServerMessageListener.java
index a6994df462edce0ea23639385c153860635afc04..f433506467718055ef929701910e23a8550f09bf 100644
--- a/core/src/main/java/io/seata/core/rpc/ServerMessageListener.java
+++ b/core/src/main/java/io/seata/core/rpc/ServerMessageListener.java
@@ -15,12 +15,12 @@
  */
 package io.seata.core.rpc;
 
+import io.netty.channel.ChannelHandlerContext;
 import io.seata.core.protocol.RegisterRMRequest;
 import io.seata.core.protocol.RegisterTMRequest;
+import io.seata.core.protocol.RpcMessage;
 import io.seata.core.rpc.netty.RegisterCheckAuthHandler;
 
-import io.netty.channel.ChannelHandlerContext;
-
 /**
  * The interface Server message listener.
  *
@@ -32,44 +32,41 @@ public interface ServerMessageListener {
     /**
      * On trx message.
      *
-     * @param msgId   the msg id
+     * @param request the msg id
      * @param ctx     the ctx
-     * @param message the message
      * @param sender  the sender
      */
-    void onTrxMessage(long msgId, ChannelHandlerContext ctx, Object message, ServerMessageSender sender);
+    void onTrxMessage(RpcMessage request, ChannelHandlerContext ctx, ServerMessageSender sender);
 
     /**
      * On reg rm message.
      *
-     * @param msgId            the msg id
+     * @param request          the msg id
      * @param ctx              the ctx
-     * @param message          the message
      * @param sender           the sender
      * @param checkAuthHandler the check auth handler
      */
-    void onRegRmMessage(long msgId, ChannelHandlerContext ctx, RegisterRMRequest message,
+    void onRegRmMessage(RpcMessage request, ChannelHandlerContext ctx,
                         ServerMessageSender sender, RegisterCheckAuthHandler checkAuthHandler);
 
     /**
      * On reg tm message.
      *
-     * @param msgId            the msg id
+     * @param request          the msg id
      * @param ctx              the ctx
-     * @param message          the message
      * @param sender           the sender
      * @param checkAuthHandler the check auth handler
      */
-    void onRegTmMessage(long msgId, ChannelHandlerContext ctx, RegisterTMRequest message,
+    void onRegTmMessage(RpcMessage request, ChannelHandlerContext ctx,
                         ServerMessageSender sender, RegisterCheckAuthHandler checkAuthHandler);
 
     /**
      * On check message.
      *
-     * @param msgId  the msg id
-     * @param ctx    the ctx
-     * @param sender the sender
+     * @param request the msg id
+     * @param ctx     the ctx
+     * @param sender  the sender
      */
-    void onCheckMessage(long msgId, ChannelHandlerContext ctx, ServerMessageSender sender);
+    void onCheckMessage(RpcMessage request, ChannelHandlerContext ctx, ServerMessageSender sender);
 
 }
diff --git a/core/src/main/java/io/seata/core/rpc/ServerMessageSender.java b/core/src/main/java/io/seata/core/rpc/ServerMessageSender.java
index 217499cc15fc4b281fadf1ce779bfbe3d8ec2278..90d94b846504729cdaa6d2e0bd522d58d4b5030d 100644
--- a/core/src/main/java/io/seata/core/rpc/ServerMessageSender.java
+++ b/core/src/main/java/io/seata/core/rpc/ServerMessageSender.java
@@ -19,6 +19,7 @@ import java.io.IOException;
 import java.util.concurrent.TimeoutException;
 
 import io.netty.channel.Channel;
+import io.seata.core.protocol.RpcMessage;
 
 /**
  * The interface Server message sender.
@@ -31,11 +32,11 @@ public interface ServerMessageSender {
     /**
      * Send response.
      *
-     * @param msgId   the msg id
+     * @param request the request
      * @param channel the channel
      * @param msg     the msg
      */
-    void sendResponse(long msgId, Channel channel, Object msg);
+    void sendResponse(RpcMessage request, Channel channel, Object msg);
 
     /**
      * Sync call to RM with timeout.
diff --git a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemoting.java b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemoting.java
index d5bf8625ca79b07c032939ee0b2cb043cecba62d..750f9321fe2adfc821e6815475e2308e6b921f51 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemoting.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemoting.java
@@ -15,6 +15,26 @@
  */
 package io.seata.core.rpc.netty;
 
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelDuplexHandler;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import io.seata.common.exception.FrameworkErrorCode;
+import io.seata.common.exception.FrameworkException;
+import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.thread.PositiveAtomicCounter;
+import io.seata.core.protocol.HeartbeatMessage;
+import io.seata.core.protocol.MergeMessage;
+import io.seata.core.protocol.MessageFuture;
+import io.seata.core.protocol.ProtocolConstants;
+import io.seata.core.protocol.RpcMessage;
+import io.seata.core.rpc.Disposable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.net.SocketAddress;
@@ -32,25 +52,6 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import io.seata.common.exception.FrameworkErrorCode;
-import io.seata.common.exception.FrameworkException;
-import io.seata.common.thread.NamedThreadFactory;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelPromise;
-import io.seata.core.protocol.HeartbeatMessage;
-import io.seata.core.protocol.MergeMessage;
-import io.seata.core.protocol.MessageFuture;
-import io.seata.core.protocol.RpcMessage;
-import io.seata.core.rpc.Disposable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * The type Abstract rpc remoting.
  *
@@ -69,15 +70,18 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
      * The Message executor.
      */
     protected final ThreadPoolExecutor messageExecutor;
+
+    /** Id generator of this remoting */
+    protected final PositiveAtomicCounter idGenerator = new PositiveAtomicCounter();
+
     /**
      * The Futures.
      */
-    protected final ConcurrentHashMap<Long, MessageFuture> futures = new ConcurrentHashMap<Long, MessageFuture>();
+    protected final ConcurrentHashMap<Integer, MessageFuture> futures = new ConcurrentHashMap<>();
     /**
      * The Basket map.
      */
-    protected final ConcurrentHashMap<String, BlockingQueue<RpcMessage>> basketMap
-        = new ConcurrentHashMap<String, BlockingQueue<RpcMessage>>();
+    protected final ConcurrentHashMap<String, BlockingQueue<RpcMessage>> basketMap = new ConcurrentHashMap<>();
 
     private static final long NOT_WRITEABLE_CHECK_MILLS = 10L;
     /**
@@ -98,7 +102,7 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     /**
      * The Merge msg map.
      */
-    protected final Map<Long, MergeMessage> mergeMsgMap = new ConcurrentHashMap<Long, MergeMessage>();
+    protected final Map<Integer, MergeMessage> mergeMsgMap = new ConcurrentHashMap<>();
     /**
      * The Channel handlers.
      */
@@ -113,6 +117,15 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
         this.messageExecutor = messageExecutor;
     }
 
+    /**
+     * Gets next message id.
+     *
+     * @return the next message id
+     */
+    public int getNextMessageId() {
+        return idGenerator.incrementAndGet();
+    }
+
     /**
      * Init.
      */
@@ -121,13 +134,11 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
             @Override
             public void run() {
                 List<MessageFuture> timeoutMessageFutures = new ArrayList<MessageFuture>(futures.size());
-
                 for (MessageFuture future : futures.values()) {
                     if (future.isTimeout()) {
                         timeoutMessageFutures.add(future);
                     }
                 }
-
                 for (MessageFuture messageFuture : timeoutMessageFutures) {
                     futures.remove(messageFuture.getRequestMessage().getId());
                     messageFuture.setResultMessage(null);
@@ -146,6 +157,7 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     @Override
     public void destroy() {
         timerExecutor.shutdown();
+        messageExecutor.shutdown();
     }
 
     @Override
@@ -162,14 +174,13 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     /**
      * Send async request with response object.
      *
-     * @param address the address
      * @param channel the channel
      * @param msg     the msg
      * @return the object
      * @throws TimeoutException the timeout exception
      */
-    protected Object sendAsyncRequestWithResponse(String address, Channel channel, Object msg) throws TimeoutException {
-        return sendAsyncRequestWithResponse(address, channel, msg, NettyClientConfig.getRpcRequestTimeout());
+    protected Object sendAsyncRequestWithResponse(Channel channel, Object msg) throws TimeoutException {
+        return sendAsyncRequestWithResponse(null, channel, msg, NettyClientConfig.getRpcRequestTimeout());
     }
 
     /**
@@ -193,15 +204,14 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     /**
      * Send async request without response object.
      *
-     * @param address the address
      * @param channel the channel
      * @param msg     the msg
      * @return the object
      * @throws TimeoutException the timeout exception
      */
-    protected Object sendAsyncRequestWithoutResponse(String address, Channel channel, Object msg) throws
+    protected Object sendAsyncRequestWithoutResponse(Channel channel, Object msg) throws
         TimeoutException {
-        return sendAsyncRequest(address, channel, msg, 0);
+        return sendAsyncRequest(null, channel, msg, 0);
     }
 
     private Object sendAsyncRequest(String address, Channel channel, Object msg, long timeout)
@@ -211,10 +221,10 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
             return null;
         }
         final RpcMessage rpcMessage = new RpcMessage();
-        rpcMessage.setId(RpcMessage.getNextMessageId());
-        rpcMessage.setAsync(false);
-        rpcMessage.setHeartbeat(false);
-        rpcMessage.setRequest(true);
+        rpcMessage.setId(getNextMessageId());
+        rpcMessage.setMessageType(ProtocolConstants.MSGTYPE_RESQUEST_ONEWAY);
+        rpcMessage.setCodec(ProtocolConstants.CONFIGURED_CODEC);
+        rpcMessage.setCompressor(ProtocolConstants.CONFIGURED_COMPRESSOR);
         rpcMessage.setBody(msg);
 
         final MessageFuture messageFuture = new MessageFuture();
@@ -226,7 +236,7 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
             ConcurrentHashMap<String, BlockingQueue<RpcMessage>> map = basketMap;
             BlockingQueue<RpcMessage> basket = map.get(address);
             if (basket == null) {
-                map.putIfAbsent(address, new LinkedBlockingQueue<RpcMessage>());
+                map.putIfAbsent(address, new LinkedBlockingQueue<>());
                 basket = map.get(address);
             }
             basket.offer(rpcMessage);
@@ -279,11 +289,13 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
      */
     protected void sendRequest(Channel channel, Object msg) {
         RpcMessage rpcMessage = new RpcMessage();
-        rpcMessage.setAsync(true);
-        rpcMessage.setHeartbeat(msg instanceof HeartbeatMessage);
-        rpcMessage.setRequest(true);
+        rpcMessage.setMessageType(msg instanceof HeartbeatMessage ?
+                ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST
+                : ProtocolConstants.MSGTYPE_RESQUEST);
+        rpcMessage.setCodec(ProtocolConstants.CONFIGURED_CODEC);
+        rpcMessage.setCompressor(ProtocolConstants.CONFIGURED_COMPRESSOR);
         rpcMessage.setBody(msg);
-        rpcMessage.setId(RpcMessage.getNextMessageId());
+        rpcMessage.setId(getNextMessageId());
         if (msg instanceof MergeMessage) {
             mergeMsgMap.put(rpcMessage.getId(), (MergeMessage)msg);
         }
@@ -298,17 +310,19 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     /**
      * Send response.
      *
-     * @param msgId   the msg id
+     * @param request  the msg id
      * @param channel the channel
      * @param msg     the msg
      */
-    protected void sendResponse(long msgId, Channel channel, Object msg) {
+    protected void sendResponse(RpcMessage request, Channel channel, Object msg) {
         RpcMessage rpcMessage = new RpcMessage();
-        rpcMessage.setAsync(true);
-        rpcMessage.setHeartbeat(msg instanceof HeartbeatMessage);
-        rpcMessage.setRequest(false);
+        rpcMessage.setMessageType(msg instanceof HeartbeatMessage ?
+                ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE :
+                ProtocolConstants.MSGTYPE_RESPONSE);
+        rpcMessage.setCodec(request.getCodec()); // same with request
+        rpcMessage.setCompressor(request.getCompressor());
         rpcMessage.setBody(msg);
-        rpcMessage.setId(msgId);
+        rpcMessage.setId(request.getId());
         channelWriteableCheck(channel, msg);
         if (LOGGER.isDebugEnabled()) {
             LOGGER.debug("send response:" + rpcMessage.getBody() + ",channel:" + channel);
@@ -344,7 +358,8 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
         if (msg instanceof RpcMessage) {
             final RpcMessage rpcMessage = (RpcMessage)msg;
-            if (rpcMessage.isRequest()) {
+            if (rpcMessage.getMessageType() == ProtocolConstants.MSGTYPE_RESQUEST
+                    || rpcMessage.getMessageType() == ProtocolConstants.MSGTYPE_RESQUEST_ONEWAY) {
                 if (LOGGER.isDebugEnabled()) {
                     LOGGER.debug(String.format("%s msgId:%s, body:%s", this, rpcMessage.getId(), rpcMessage.getBody()));
                 }
@@ -353,7 +368,7 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
                         @Override
                         public void run() {
                             try {
-                                dispatch(rpcMessage.getId(), ctx, rpcMessage.getBody());
+                                dispatch(rpcMessage, ctx);
                             } catch (Throwable th) {
                                 LOGGER.error(FrameworkErrorCode.NetDispatch.getErrCode(), th.getMessage(), th);
                             }
@@ -389,7 +404,7 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
                             @Override
                             public void run() {
                                 try {
-                                    dispatch(rpcMessage.getId(), ctx, rpcMessage.getBody());
+                                    dispatch(rpcMessage, ctx);
                                 } catch (Throwable th) {
                                     LOGGER.error(FrameworkErrorCode.NetDispatch.getErrCode(), th.getMessage(), th);
                                 }
@@ -419,11 +434,10 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
     /**
      * Dispatch.
      *
-     * @param msgId the msg id
-     * @param ctx   the ctx
-     * @param msg   the msg
+     * @param request the request
+     * @param ctx     the ctx
      */
-    public abstract void dispatch(long msgId, ChannelHandlerContext ctx, Object msg);
+    public abstract void dispatch(RpcMessage request, ChannelHandlerContext ctx);
 
     @Override
     public void close(ChannelHandlerContext ctx, ChannelPromise future) throws Exception {
@@ -513,6 +527,4 @@ public abstract class AbstractRpcRemoting extends ChannelDuplexHandler implement
         }
         return address;
     }
-
-
 }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingClient.java b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingClient.java
index 342c0d5015fc4e881ee4bd354edeb7d1e5a34691..b9f7919065a98da1d406c896f75eca850fce70bb 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingClient.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingClient.java
@@ -15,272 +15,138 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.util.concurrent.EventExecutorGroup;
 import io.seata.common.exception.FrameworkErrorCode;
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.thread.NamedThreadFactory;
-import io.seata.common.util.CollectionUtils;
 import io.seata.common.util.NetUtil;
 import io.seata.core.protocol.AbstractMessage;
 import io.seata.core.protocol.HeartbeatMessage;
 import io.seata.core.protocol.MergeResultMessage;
 import io.seata.core.protocol.MergedWarpMessage;
 import io.seata.core.protocol.MessageFuture;
+import io.seata.core.protocol.ResultCode;
 import io.seata.core.protocol.RpcMessage;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
 import io.seata.core.rpc.ClientMessageListener;
 import io.seata.core.rpc.ClientMessageSender;
-import io.seata.core.rpc.RemotingService;
-
 import io.seata.discovery.loadbalance.LoadBalanceFactory;
 import io.seata.discovery.registry.RegistryFactory;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.epoll.EpollChannelOption;
-import io.netty.channel.epoll.EpollMode;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.pool.AbstractChannelPoolMap;
-import io.netty.channel.pool.ChannelHealthChecker;
-import io.netty.channel.pool.FixedChannelPool;
-import io.netty.channel.pool.FixedChannelPool.AcquireTimeoutAction;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.handler.timeout.IdleStateHandler;
-import io.netty.util.concurrent.DefaultEventExecutorGroup;
-import io.netty.util.concurrent.EventExecutorGroup;
-import io.netty.util.internal.PlatformDependent;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool.Config;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.function.Function;
+
 import static io.seata.common.exception.FrameworkErrorCode.NoAvailableService;
 
 /**
  * The type Rpc remoting client.
  *
  * @author jimin.jm @alibaba-inc.com
+ * @author zhaojun
  * @date 2018 /9/12
  */
 public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
-    implements RemotingService, RegisterMsgListener, ClientMessageSender {
+    implements RegisterMsgListener, ClientMessageSender {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRpcRemotingClient.class);
-    private final NettyClientConfig nettyClientConfig;
-    private final Bootstrap bootstrap = new Bootstrap();
-    private final EventLoopGroup eventLoopGroupWorker;
-    private EventExecutorGroup defaultEventExecutorGroup;
-    private AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool> clientChannelPool;
-    private final AtomicBoolean initialized = new AtomicBoolean(false);
     private static final String MSG_ID_PREFIX = "msgId:";
     private static final String FUTURES_PREFIX = "futures:";
     private static final String SINGLE_LOG_POSTFIX = ";";
     private static final int MAX_MERGE_SEND_MILLS = 1;
     private static final String THREAD_PREFIX_SPLIT_CHAR = "_";
-
-
-    /**
-     * The Netty client key pool.
-     */
-    protected GenericKeyedObjectPool<NettyPoolKey, Channel> nettyClientKeyPool;
-    /**
-     * The Client message listener.
-     */
-    protected ClientMessageListener clientMessageListener;
-
-    /**
-     * Instantiates a new Rpc remoting client.
-     *
-     * @param nettyClientConfig the netty client config
-     */
-    public AbstractRpcRemotingClient(final NettyClientConfig nettyClientConfig) {
-        this(nettyClientConfig, null, null);
+    
+    private static final int MAX_MERGE_SEND_THREAD = 1;
+    private static final long KEEP_ALIVE_TIME = Integer.MAX_VALUE;
+    private static final int SCHEDULE_INTERVAL_MILLS = 5;
+    private static final String MERGE_THREAD_PREFIX = "rpcMergeMessageSend";
+    
+    private final RpcClientBootstrap clientBootstrap;
+    private NettyClientChannelManager clientChannelManager;
+    private ClientMessageListener clientMessageListener;
+    private final NettyPoolKey.TransactionRole transactionRole;
+    private ExecutorService mergeSendExecutorService;
+    
+    public AbstractRpcRemotingClient(NettyClientConfig nettyClientConfig, EventExecutorGroup eventExecutorGroup,
+                                     ThreadPoolExecutor messageExecutor, NettyPoolKey.TransactionRole transactionRole) {
+        super(messageExecutor);
+        this.transactionRole = transactionRole;
+        clientBootstrap = new RpcClientBootstrap(nettyClientConfig, eventExecutorGroup, this, transactionRole);
+        clientChannelManager = new NettyClientChannelManager(
+            new NettyPoolableFactory(this, clientBootstrap), getPoolKeyFunction(), nettyClientConfig);
     }
-
+    
+    public NettyClientChannelManager getClientChannelManager() {
+        return clientChannelManager;
+    }
+    
     /**
-     * Instantiates a new Rpc remoting client.
+     * Get pool key function.
      *
-     * @param nettyClientConfig  the netty client config
-     * @param eventExecutorGroup the event executor group
-     * @param messageExecutor    the message executor
+     * @return lambda function
      */
-    public AbstractRpcRemotingClient(NettyClientConfig nettyClientConfig, final EventExecutorGroup eventExecutorGroup,
-                                     final ThreadPoolExecutor messageExecutor) {
-        super(messageExecutor);
-        if (null == nettyClientConfig) {
-            nettyClientConfig = new NettyClientConfig();
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("use default netty client config.");
-            }
-        }
-        this.nettyClientConfig = nettyClientConfig;
-        int selectorThreadSizeThreadSize = this.nettyClientConfig.getClientSelectorThreadSize();
-        this.eventLoopGroupWorker = new NioEventLoopGroup(selectorThreadSizeThreadSize,
-            new NamedThreadFactory(getThreadPrefix(this.nettyClientConfig.getClientSelectorThreadPrefix()),
-                selectorThreadSizeThreadSize));
-        this.defaultEventExecutorGroup = eventExecutorGroup;
-    }
-
-    @Override
-    public void init() {
-        NettyPoolableFactory keyPoolableFactory = new NettyPoolableFactory(this);
-        nettyClientKeyPool = new GenericKeyedObjectPool(keyPoolableFactory);
-        nettyClientKeyPool.setConfig(getNettyPoolConfig());
-        super.init();
-    }
-
-    @Override
-    public void start() {
-
-        if (this.defaultEventExecutorGroup == null) {
-            this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(nettyClientConfig.getClientWorkerThreads(),
-                new NamedThreadFactory(getThreadPrefix(nettyClientConfig.getClientWorkerThreadPrefix()),
-                    nettyClientConfig.getClientWorkerThreads()));
-        }
-        this.bootstrap.group(this.eventLoopGroupWorker).channel(
-            nettyClientConfig.getClientChannelClazz()).option(
-            ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true).option(
-            ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyClientConfig.getConnectTimeoutMillis()).option(
-            ChannelOption.SO_SNDBUF, nettyClientConfig.getClientSocketSndBufSize()).option(ChannelOption.SO_RCVBUF,
-            nettyClientConfig.getClientSocketRcvBufSize());
-
-        if (nettyClientConfig.enableNative()) {
-            if (PlatformDependent.isOsx()) {
-                if (LOGGER.isInfoEnabled()) {
-                    LOGGER.info("client run on macOS");
-                }
-            } else {
-                bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
-                    .option(EpollChannelOption.TCP_QUICKACK, true);
-            }
-        }
-        if (nettyClientConfig.isUseConnPool()) {
-            clientChannelPool = new AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool>() {
-                @Override
-                protected FixedChannelPool newPool(InetSocketAddress key) {
-                    FixedChannelPool fixedClientChannelPool = new FixedChannelPool(
-                        bootstrap.remoteAddress(key),
-                        new DefaultChannelPoolHandler() {
-                            @Override
-                            public void channelCreated(Channel ch) throws Exception {
-                                super.channelCreated(ch);
-                                final ChannelPipeline pipeline = ch.pipeline();
-                                pipeline.addLast(defaultEventExecutorGroup,
-                                    new IdleStateHandler(nettyClientConfig.getChannelMaxReadIdleSeconds(),
-                                        nettyClientConfig.getChannelMaxWriteIdleSeconds(),
-                                        nettyClientConfig.getChannelMaxAllIdleSeconds()));
-                                pipeline.addLast(defaultEventExecutorGroup, new RpcClientHandler());
-                            }
-                        },
-                        ChannelHealthChecker.ACTIVE,
-                        AcquireTimeoutAction.FAIL,
-                        nettyClientConfig.getMaxAcquireConnMills(),
-                        nettyClientConfig.getPerHostMaxConn(),
-                        nettyClientConfig.getPendingConnSize(),
-                        false
-                    );
-                    return fixedClientChannelPool;
-
-                }
-            };
-        } else {
-            bootstrap.handler(
-                new ChannelInitializer<SocketChannel>() {
-
-                    @Override
-                    public void initChannel(SocketChannel ch) {
-                        ChannelPipeline pipeline = ch.pipeline();
-                        pipeline.addLast(
-                            new IdleStateHandler(nettyClientConfig.getChannelMaxReadIdleSeconds(),
-                                nettyClientConfig.getChannelMaxWriteIdleSeconds(),
-                                nettyClientConfig.getChannelMaxAllIdleSeconds()))
-                            .addLast(new MessageCodecHandler());
-                        if (null != channelHandlers) {
-                            addChannelPipelineLast(ch, channelHandlers);
-                        }
-                    }
-                });
-        }
-        if (initialized.compareAndSet(false, true) && LOGGER.isInfoEnabled()) {
-            LOGGER.info("AbstractRpcRemotingClient has started");
-        }
-    }
-
+    protected abstract Function<String, NettyPoolKey> getPoolKeyFunction();
+    
     /**
-     * Gets new channel.
+     * Get transaction service group.
      *
-     * @param address the address
-     * @return the new channel
+     * @return transaction service group
      */
-    protected Channel getNewChannel(InetSocketAddress address) {
-        Channel channel = null;
-        ChannelFuture f = this.bootstrap.connect(address);
-        try {
-            f.await(this.nettyClientConfig.getConnectTimeoutMillis(), TimeUnit.MILLISECONDS);
-            if (f.isCancelled()) {
-                throw new FrameworkException(f.cause(), "connect cancelled, can not connect to services-server.");
-            } else if (!f.isSuccess()) {
-                throw new FrameworkException(f.cause(), "connect failed, can not connect to services-server.");
-            } else {
-                channel = f.channel();
-            }
-        } catch (Exception e) {
-            throw new FrameworkException(e, "can not connect to services-server.");
-        }
-        return channel;
-    }
+    protected abstract String getTransactionServiceGroup();
 
     @Override
-    public void shutdown() {
-        try {
-            if (null != clientChannelPool) {
-                clientChannelPool.close();
-            }
-            this.eventLoopGroupWorker.shutdownGracefully();
-            if (this.defaultEventExecutorGroup != null) {
-                this.defaultEventExecutorGroup.shutdownGracefully();
+    public void init() {
+        clientBootstrap.start();
+        timerExecutor.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+                clientChannelManager.reconnect(getTransactionServiceGroup());
             }
-            super.destroy();
-        } catch (Exception exx) {
-            LOGGER.error("Failed to shutdown: {}", exx.getMessage());
-        }
+        }, SCHEDULE_INTERVAL_MILLS, SCHEDULE_INTERVAL_MILLS, TimeUnit.SECONDS);
+        mergeSendExecutorService = new ThreadPoolExecutor(MAX_MERGE_SEND_THREAD,
+            MAX_MERGE_SEND_THREAD,
+            KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
+            new LinkedBlockingQueue<>(),
+            new NamedThreadFactory(getThreadPrefix(), MAX_MERGE_SEND_THREAD));
+        mergeSendExecutorService.submit(new MergedSendRunnable());
+        super.init();
     }
-
+    
     @Override
     public void destroy() {
-        super.destroy();
-        shutdown();
+        clientBootstrap.shutdown();
+        mergeSendExecutorService.shutdown();
     }
-
+    
     @Override
     public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
-        if (msg instanceof RpcMessage) {
-            RpcMessage rpcMessage = (RpcMessage) msg;
-            if (rpcMessage.getBody() == HeartbeatMessage.PONG) {
-                if (LOGGER.isDebugEnabled()) {
-                    LOGGER.debug("received PONG from {}", ctx.channel().remoteAddress());
-                }
-                return;
+        if (!(msg instanceof RpcMessage)) {
+            return;
+        }
+        RpcMessage rpcMessage = (RpcMessage) msg;
+        if (rpcMessage.getBody() == HeartbeatMessage.PONG) {
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("received PONG from {}", ctx.channel().remoteAddress());
             }
+            return;
         }
-
-        if (((RpcMessage) msg).getBody() instanceof MergeResultMessage) {
-            MergeResultMessage results = (MergeResultMessage) ((RpcMessage) msg).getBody();
-            MergedWarpMessage mergeMessage = (MergedWarpMessage) mergeMsgMap.remove(((RpcMessage) msg).getId());
-            int num = mergeMessage.msgs.size();
-            for (int i = 0; i < num; i++) {
-                long msgId = mergeMessage.msgIds.get(i);
+        if (rpcMessage.getBody() instanceof MergeResultMessage) {
+            MergeResultMessage results = (MergeResultMessage) rpcMessage.getBody();
+            MergedWarpMessage mergeMessage = (MergedWarpMessage) mergeMsgMap.remove(rpcMessage.getId());
+            for (int i = 0; i < mergeMessage.msgs.size(); i++) {
+                int msgId = mergeMessage.msgIds.get(i);
                 MessageFuture future = futures.remove(msgId);
                 if (future == null) {
                     if (LOGGER.isInfoEnabled()) {
@@ -294,6 +160,14 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
         }
         super.channelRead(ctx, msg);
     }
+    
+    @Override
+    public void dispatch(RpcMessage request, ChannelHandlerContext ctx) {
+        if (clientMessageListener != null) {
+            String remoteAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
+            clientMessageListener.onMessage(request, remoteAddress, this);
+        }
+    }
 
     @Override
     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
@@ -303,10 +177,80 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("channel inactive: {}", ctx.channel());
         }
-        releaseChannel(ctx.channel(), NetUtil.toStringAddress(ctx.channel().remoteAddress()));
+        clientChannelManager.releaseChannel(ctx.channel(), NetUtil.toStringAddress(ctx.channel().remoteAddress()));
         super.channelInactive(ctx);
     }
-
+    
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
+        if (evt instanceof IdleStateEvent) {
+            IdleStateEvent idleStateEvent = (IdleStateEvent)evt;
+            if (idleStateEvent.state() == IdleState.READER_IDLE) {
+                if (LOGGER.isInfoEnabled()) {
+                    LOGGER.info("channel" + ctx.channel() + " read idle.");
+                }
+                try {
+                    String serverAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
+                    clientChannelManager.invalidateObject(serverAddress, ctx.channel());
+                } catch (Exception exx) {
+                    LOGGER.error(exx.getMessage());
+                } finally {
+                    clientChannelManager.releaseChannel(ctx.channel(), getAddressFromContext(ctx));
+                }
+            }
+            if (idleStateEvent == IdleStateEvent.WRITER_IDLE_STATE_EVENT) {
+                try {
+                    if (LOGGER.isDebugEnabled()) {
+                        LOGGER.debug("will send ping msg,channel" + ctx.channel());
+                    }
+                    sendRequest(ctx.channel(), HeartbeatMessage.PING);
+                } catch (Throwable throwable) {
+                    LOGGER.error("", "send request error", throwable);
+                }
+            }
+        }
+    }
+    
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        LOGGER.error(FrameworkErrorCode.ExceptionCaught.getErrCode(),
+            NetUtil.toStringAddress(ctx.channel().remoteAddress()) + "connect exception. " + cause.getMessage(), cause);
+        clientChannelManager.releaseChannel(ctx.channel(), getAddressFromChannel(ctx.channel()));
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("remove exception rm channel:" + ctx.channel());
+        }
+        super.exceptionCaught(ctx, cause);
+    }
+    
+    @Override
+    public Object sendMsgWithResponse(Object msg, long timeout) throws TimeoutException {
+        String validAddress = loadBalance(getTransactionServiceGroup());
+        Channel channel = clientChannelManager.acquireChannel(validAddress);
+        Object result = super.sendAsyncRequestWithResponse(validAddress, channel, msg, timeout);
+        if (result instanceof GlobalBeginResponse
+            && ((GlobalBeginResponse) result).getResultCode() == ResultCode.Failed) {
+            LOGGER.error("begin response error,release channel:" + channel);
+            clientChannelManager.releaseChannel(channel, validAddress);
+        }
+        return result;
+    }
+    
+    @Override
+    public Object sendMsgWithResponse(Object msg) throws TimeoutException {
+        return sendMsgWithResponse(msg, NettyClientConfig.getRpcRequestTimeout());
+    }
+    
+    @Override
+    public Object sendMsgWithResponse(String serverAddress, Object msg, long timeout)
+        throws TimeoutException {
+        return sendAsyncRequestWithResponse(serverAddress, clientChannelManager.acquireChannel(serverAddress), msg, timeout);
+    }
+    
+    @Override
+    public void sendResponse(RpcMessage request, String serverAddress, Object msg) {
+        super.sendResponse(request, clientChannelManager.acquireChannel(serverAddress), msg);
+    }
+    
     /**
      * Gets client message listener.
      *
@@ -315,7 +259,7 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
     public ClientMessageListener getClientMessageListener() {
         return clientMessageListener;
     }
-
+    
     /**
      * Sets client message listener.
      *
@@ -326,112 +270,32 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
     }
 
     @Override
-    public void dispatch(long msgId, ChannelHandlerContext ctx, Object msg) {
-        if (clientMessageListener != null) {
-            String remoteAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
-            clientMessageListener.onMessage(msgId, remoteAddress, msg, this);
-        }
+    public void destroyChannel(String serverAddress, Channel channel) {
+        clientChannelManager.destroyChannel(serverAddress, channel);
     }
-
-    protected void reconnect(String transactionServiceGroup) {
-        List<String> availList = null;
-        try {
-            availList = getAvailServerList(transactionServiceGroup);
-        } catch (Exception exx) {
-            LOGGER.error("Failed to get available servers: {}" + exx.getMessage());
-        }
-        if (CollectionUtils.isEmpty(availList)) {
-            LOGGER.error("no available server to connect.");
-            return;
-        }
-        for (String serverAddress : availList) {
-            try {
-                connect(serverAddress);
-            } catch (Exception e) {
-                LOGGER.error(FrameworkErrorCode.NetConnect.getErrCode(),
-                    "can not connect to " + serverAddress + " cause:" + e.getMessage(), e);
-            }
-        }
-    }
-
-    /**
-     * Gets avail server list.
-     *
-     * @param transactionServiceGroup the transaction service group
-     * @return the avail server list
-     * @throws Exception the exception
-     */
-    protected List<String> getAvailServerList(String transactionServiceGroup) throws Exception {
-        List<String> availList = new ArrayList<>();
-        List<InetSocketAddress> availInetSocketAddressList = RegistryFactory.getInstance().lookup(
-            transactionServiceGroup);
-        if (!CollectionUtils.isEmpty(availInetSocketAddressList)) {
-            for (InetSocketAddress address : availInetSocketAddressList) {
-                availList.add(NetUtil.toStringAddress(address));
-            }
-        }
-        return availList;
-    }
-
-    protected String loadBalance(String transactionServiceGroup) {
+    
+    private String loadBalance(String transactionServiceGroup) {
         InetSocketAddress address = null;
         try {
-            List<InetSocketAddress> inetSocketAddressList = RegistryFactory.getInstance().lookup(
-                transactionServiceGroup);
+            List<InetSocketAddress> inetSocketAddressList = RegistryFactory.getInstance().lookup(transactionServiceGroup);
             address = LoadBalanceFactory.getInstance().select(inetSocketAddressList);
-        } catch (Exception ignore) {
-            LOGGER.error(ignore.getMessage());
+        } catch (Exception ex) {
+            LOGGER.error(ex.getMessage());
         }
         if (address == null) {
             throw new FrameworkException(NoAvailableService);
         }
         return NetUtil.toStringAddress(address);
     }
-
-    /**
-     * Gets thread prefix.
-     *
-     * @param threadPrefix the thread prefix
-     * @return the thread prefix
-     */
-    protected String getThreadPrefix(String threadPrefix) {
-        return threadPrefix + THREAD_PREFIX_SPLIT_CHAR + getTransactionRole().name();
+    
+    private String getThreadPrefix() {
+        return AbstractRpcRemotingClient.MERGE_THREAD_PREFIX + THREAD_PREFIX_SPLIT_CHAR + transactionRole.name();
     }
 
-    /**
-     * Connect channel.
-     *
-     * @param serverAddress the server address
-     * @return the channel
-     */
-    protected abstract Channel connect(String serverAddress);
-
-    /**
-     * Release channel.
-     *
-     * @param channel       the channel
-     * @param serverAddress the server address
-     */
-    protected abstract void releaseChannel(Channel channel, String serverAddress);
-
-    /**
-     * Gets netty pool config.
-     *
-     * @return the netty pool config
-     */
-    protected abstract Config getNettyPoolConfig();
-
-    /**
-     * Gets transaction role.
-     *
-     * @return the transaction role
-     */
-    protected abstract NettyPoolKey.TransactionRole getTransactionRole();
-
     /**
      * The type Merged send runnable.
      */
-    public class MergedSendRunnable implements Runnable {
+    private class MergedSendRunnable implements Runnable {
 
         @Override
         public void run() {
@@ -460,15 +324,14 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
                     }
                     Channel sendChannel = null;
                     try {
-                        sendChannel = connect(address);
+                        sendChannel = clientChannelManager.acquireChannel(address);
                         sendRequest(sendChannel, mergeMessage);
                     } catch (FrameworkException e) {
-                        if (e.getErrcode() == FrameworkErrorCode.ChannelIsNotWritable
-                            && address != null && sendChannel != null) {
+                        if (e.getErrcode() == FrameworkErrorCode.ChannelIsNotWritable && sendChannel != null) {
                             destroyChannel(address, sendChannel);
                         }
                         // fast fail
-                        for (Long msgId : mergeMessage.msgIds) {
+                        for (Integer msgId : mergeMessage.msgIds) {
                             MessageFuture messageFuture = futures.remove(msgId);
                             if (messageFuture != null) {
                                 messageFuture.setResultMessage(null);
@@ -487,7 +350,7 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
                 for (AbstractMessage cm : mergeMessage.msgs) {
                     LOGGER.debug(cm.toString());
                 }
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 for (long l : mergeMessage.msgIds) {
                     sb.append(MSG_ID_PREFIX).append(l).append(SINGLE_LOG_POSTFIX);
                 }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingServer.java b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingServer.java
index e58a60a57c9f348efc6c9a7ec5d4a69eeac6e162..9ee039d79640b6cc0d56cdcd88a1bb477e199a70 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingServer.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/AbstractRpcRemotingServer.java
@@ -15,11 +15,6 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.net.InetSocketAddress;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
@@ -34,15 +29,24 @@ import io.netty.channel.socket.SocketChannel;
 import io.netty.handler.timeout.IdleStateHandler;
 import io.seata.common.XID;
 import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.util.NetUtil;
 import io.seata.core.rpc.RemotingServer;
+import io.seata.core.rpc.netty.v1.ProtocolV1Decoder;
+import io.seata.core.rpc.netty.v1.ProtocolV1Encoder;
 import io.seata.discovery.registry.RegistryFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.InetSocketAddress;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 /**
  * The type Rpc remoting server.
  *
  * @author jimin.jm @alibaba-inc.com
+ * @author xingfudeshi@gmail.com
  * @date 2018 /9/12
  */
 public abstract class AbstractRpcRemotingServer extends AbstractRpcRemoting implements RemotingServer {
@@ -52,6 +56,7 @@ public abstract class AbstractRpcRemotingServer extends AbstractRpcRemoting impl
     private final EventLoopGroup eventLoopGroupBoss;
     private final NettyServerConfig nettyServerConfig;
     private int listenPort;
+    private String host;
     private final AtomicBoolean initialized = new AtomicBoolean(false);
 
     /**
@@ -76,6 +81,27 @@ public abstract class AbstractRpcRemotingServer extends AbstractRpcRemoting impl
         return listenPort;
     }
 
+    /**
+     * Gets the host
+     *
+     * @return
+     */
+    public String getHost() {
+        return this.host;
+    }
+
+    /**
+     * Sets the host
+     *
+     * @param host
+     */
+    public void setHost(String host) {
+        if (!NetUtil.isValidIp(host, true)) {
+            throw new IllegalArgumentException("host: " + host + " is invalid!");
+        }
+        this.host = host;
+    }
+
     /**
      * Instantiates a new Rpc remoting server.
      *
@@ -135,7 +161,8 @@ public abstract class AbstractRpcRemotingServer extends AbstractRpcRemoting impl
                 @Override
                 public void initChannel(SocketChannel ch) {
                     ch.pipeline().addLast(new IdleStateHandler(nettyServerConfig.getChannelMaxReadIdleSeconds(), 0, 0))
-                        .addLast(new MessageCodecHandler());
+                            .addLast(new ProtocolV1Decoder())
+                            .addLast(new ProtocolV1Encoder());
                     if (null != channelHandlers) {
                         addChannelPipelineLast(ch, channelHandlers);
                     }
@@ -148,7 +175,7 @@ public abstract class AbstractRpcRemotingServer extends AbstractRpcRemoting impl
         }
 
         try {
-            ChannelFuture future = this.serverBootstrap.bind(listenPort).sync();
+            ChannelFuture future = this.serverBootstrap.bind(host, listenPort).sync();
             LOGGER.info("Server started ... ");
             RegistryFactory.getInstance().register(new InetSocketAddress(XID.getIpAddress(), XID.getPort()));
             initialized.set(true);
diff --git a/core/src/main/java/io/seata/core/rpc/netty/MessageCodecHandler.java b/core/src/main/java/io/seata/core/rpc/netty/MessageCodecHandler.java
deleted file mode 100644
index cf804234be79579cd90235ecb4a7f2984fb79c59..0000000000000000000000000000000000000000
--- a/core/src/main/java/io/seata/core/rpc/netty/MessageCodecHandler.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- *  Copyright 1999-2019 Seata.io Group.
- *
- *  Licensed 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 io.seata.core.rpc.netty;
-
-import java.nio.ByteBuffer;
-import java.util.List;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageCodec;
-import io.seata.core.protocol.AbstractMessage;
-import io.seata.core.protocol.HeartbeatMessage;
-import io.seata.core.protocol.MessageCodec;
-import io.seata.core.protocol.RpcMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The type Message codec handler.
- * RpcMessage protocol
- * 0     1     2     3     4           6           8          10           12          14         16
- * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
- * |   0xdada  |   flag    | typecode/ |                 requestid                     |           |
- * |           |           | bodylength|                                               |           |
- * +-----------+-----------+-----------+-----------+-----------+-----------+-----------+           +
- * |                                    ... ...                                                    |
- * +                                                                                               +
- * |                                     body                                                      |
- * +                                                                                               +
- * |                                    ... ...                                                    |
- * +-----------------------------------------------------------------------------------------------+
- *
- * @author jimin.jm @alibaba-inc.com
- * @date 2018 /9/14
- */
-public class MessageCodecHandler extends ByteToMessageCodec<RpcMessage> {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(MessageCodecHandler.class);
-    private static short MAGIC = (short)0xdada;
-    private static int HEAD_LENGTH = 14;
-    private static final int FLAG_REQUEST = 0x80;
-    private static final int FLAG_ASYNC = 0x40;
-    private static final int FLAG_HEARTBEAT = 0x20;
-    private static final int FLAG_SEATA_CODEC = 0x10;
-    private static final int MAGIC_HALF = -38;
-    private static final int NOT_FOUND_INDEX = -1;
-
-    @Override
-    protected void encode(ChannelHandlerContext ctx, RpcMessage msg, ByteBuf out) throws Exception {
-        MessageCodec msgCodec = null;
-        ByteBuffer byteBuffer = ByteBuffer.allocate(128);
-        if (msg.getBody() instanceof MessageCodec) {
-            msgCodec = (MessageCodec)msg.getBody();
-        }
-        byteBuffer.putShort(MAGIC);
-        int flag = (msg.isAsync() ? FLAG_ASYNC : 0)
-            | (msg.isHeartbeat() ? FLAG_HEARTBEAT : 0)
-            | (msg.isRequest() ? FLAG_REQUEST : 0)
-            | (msgCodec != null ? FLAG_SEATA_CODEC : 0);
-
-        byteBuffer.putShort((short)flag);
-
-        if (msg.getBody() instanceof HeartbeatMessage) {
-            byteBuffer.putShort((short)0);
-            byteBuffer.putLong(msg.getId());
-            byteBuffer.flip();
-            out.writeBytes(byteBuffer);
-            return;
-        }
-
-        try {
-            if (null != msgCodec) {
-                byteBuffer.putShort(msgCodec.getTypeCode());
-                byteBuffer.putLong(msg.getId());
-
-                byteBuffer.flip();
-                out.writeBytes(byteBuffer);
-                out.writeBytes(msgCodec.encode());
-            } else {
-                if (LOGGER.isInfoEnabled()) {
-                    LOGGER.info("msg:" + msg.getBody().toString());
-                }
-                byte[] body = hessianSerialize(msg.getBody());
-                byteBuffer.putShort((short)body.length);
-                byteBuffer.putLong(msg.getId());
-                byteBuffer.put(body);
-
-                byteBuffer.flip();
-                out.writeBytes(byteBuffer);
-            }
-        } catch (Exception e) {
-            LOGGER.error(msg.getBody() + " encode error", "", e);
-            throw e;
-        }
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Send:" + msg.getBody());
-        }
-    }
-
-    @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
-
-        if (in.readableBytes() < HEAD_LENGTH) {
-            return;
-        }
-        in.markReaderIndex();
-        short protocol = in.readShort();
-        if (protocol != MAGIC) {
-            String emsg = "decode error,Unknown protocol: " + protocol + ",will close channel:" + ctx.channel();
-            LOGGER.error(emsg);
-            ctx.channel().close();
-            return;
-        }
-
-        int flag = (int)in.readShort();
-
-        boolean isHeartbeat = (FLAG_HEARTBEAT & flag) > 0;
-        boolean isRequest = (FLAG_REQUEST & flag) > 0;
-        boolean isSeataCodec = (FLAG_SEATA_CODEC & flag) > 0;
-
-        short bodyLength = 0;
-        short typeCode = 0;
-        if (!isSeataCodec) { bodyLength = in.readShort(); } else { typeCode = in.readShort(); }
-        long msgId = in.readLong();
-        if (isHeartbeat) {
-            RpcMessage rpcMessage = new RpcMessage();
-            rpcMessage.setId(msgId);
-            rpcMessage.setAsync(true);
-            rpcMessage.setHeartbeat(isHeartbeat);
-            rpcMessage.setRequest(isRequest);
-            if (isRequest) {
-                rpcMessage.setBody(HeartbeatMessage.PING);
-            } else {
-                rpcMessage.setBody(HeartbeatMessage.PONG);
-            }
-            out.add(rpcMessage);
-            return;
-        }
-
-        if (bodyLength > 0 && in.readableBytes() < bodyLength) {
-            in.resetReaderIndex();
-            return;
-        }
-
-        RpcMessage rpcMessage = new RpcMessage();
-        rpcMessage.setId(msgId);
-        rpcMessage.setAsync((FLAG_ASYNC & flag) > 0);
-        rpcMessage.setHeartbeat(false);
-        rpcMessage.setRequest(isRequest);
-
-        try {
-            if (isSeataCodec) {
-                MessageCodec msgCodec = AbstractMessage.getMsgInstanceByCode(typeCode);
-                if (!msgCodec.decode(in)) {
-                    in.resetReaderIndex();
-                    return;
-                }
-                rpcMessage.setBody(msgCodec);
-            } else {
-                byte[] body = new byte[bodyLength];
-                in.readBytes(body);
-                Object bodyObject = hessianDeserialize(body);
-                rpcMessage.setBody(bodyObject);
-            }
-        } catch (Exception e) {
-            LOGGER.error("decode error", "", e);
-            throw e;
-        }
-        out.add(rpcMessage);
-        if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Receive:" + rpcMessage.getBody() + ",messageId:"
-                + msgId);
-        }
-
-    }
-
-    /**
-     * Hessian serialize byte [ ].
-     *
-     * @param object the object
-     * @return the byte [ ]
-     * @throws Exception the exception
-     */
-    private static byte[] hessianSerialize(Object object) throws Exception {
-        if (object == null) {
-            throw new NullPointerException();
-        }
-        //todo user defined exx
-        throw new RuntimeException("hessianSerialize not support");
-
-    }
-
-    /**
-     * Hessian deserialize object.
-     *
-     * @param bytes the bytes
-     * @return the object
-     * @throws Exception the exception
-     */
-    private static Object hessianDeserialize(byte[] bytes) throws Exception {
-        if (bytes == null) {
-            throw new NullPointerException();
-        }
-        //todo user defined exx
-        throw new RuntimeException("hessianDeserialize not support");
-
-    }
-}
diff --git a/core/src/main/java/io/seata/core/rpc/netty/NettyClientChannelManager.java b/core/src/main/java/io/seata/core/rpc/netty/NettyClientChannelManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..3985407238041e9f0c0051505f19f797c0c772e8
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/netty/NettyClientChannelManager.java
@@ -0,0 +1,249 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty;
+
+import io.netty.channel.Channel;
+import io.seata.common.exception.FrameworkErrorCode;
+import io.seata.common.exception.FrameworkException;
+import io.seata.common.util.CollectionUtils;
+import io.seata.common.util.NetUtil;
+import io.seata.core.protocol.RegisterRMRequest;
+import io.seata.discovery.registry.RegistryFactory;
+import org.apache.commons.pool.impl.GenericKeyedObjectPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
+/**
+ * Netty client pool manager.
+ *
+ * @author jimin.jm @alibaba-inc.com
+ * @author zhaojun
+ */
+class NettyClientChannelManager {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(NettyClientChannelManager.class);
+    
+    private final ConcurrentMap<String, Object> channelLocks = new ConcurrentHashMap<>();
+    
+    private final ConcurrentMap<String, NettyPoolKey> poolKeyMap = new ConcurrentHashMap<>();
+    
+    private final ConcurrentMap<String, Channel> channels = new ConcurrentHashMap<>();
+    
+    private final GenericKeyedObjectPool<NettyPoolKey, Channel> nettyClientKeyPool;
+    
+    private Function<String, NettyPoolKey> poolKeyFunction;
+    
+    NettyClientChannelManager(final NettyPoolableFactory keyPoolableFactory, final Function<String, NettyPoolKey> poolKeyFunction,
+                                     final NettyClientConfig clientConfig) {
+        nettyClientKeyPool = new GenericKeyedObjectPool<>(keyPoolableFactory);
+        nettyClientKeyPool.setConfig(getNettyPoolConfig(clientConfig));
+        this.poolKeyFunction = poolKeyFunction;
+    }
+    
+    private GenericKeyedObjectPool.Config getNettyPoolConfig(final NettyClientConfig clientConfig) {
+        GenericKeyedObjectPool.Config poolConfig = new GenericKeyedObjectPool.Config();
+        poolConfig.maxActive = clientConfig.getMaxPoolActive();
+        poolConfig.minIdle = clientConfig.getMinPoolIdle();
+        poolConfig.maxWait = clientConfig.getMaxAcquireConnMills();
+        poolConfig.testOnBorrow = clientConfig.isPoolTestBorrow();
+        poolConfig.testOnReturn = clientConfig.isPoolTestReturn();
+        poolConfig.lifo = clientConfig.isPoolLifo();
+        return poolConfig;
+    }
+    
+    /**
+     * Get all channels registered on current Rpc Client.
+     *
+     * @return channels
+     */
+    ConcurrentMap<String, Channel> getChannels() {
+        return channels;
+    }
+    
+    /**
+     * Acquire netty client channel connected to remote server.
+     *
+     * @param serverAddress server address
+     * @return netty channel
+     */
+    Channel acquireChannel(String serverAddress) {
+        Channel channelToServer = channels.get(serverAddress);
+        if (channelToServer != null) {
+            channelToServer = getExistAliveChannel(channelToServer, serverAddress);
+            if (null != channelToServer) {
+                return channelToServer;
+            }
+        }
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("will connect to " + serverAddress);
+        }
+        channelLocks.putIfAbsent(serverAddress, new Object());
+        synchronized (channelLocks.get(serverAddress)) {
+            return doConnect(serverAddress);
+        }
+    }
+    
+    /**
+     * Release channel to pool if necessary.
+     *
+     * @param channel channel
+     * @param serverAddress server address
+     */
+    void releaseChannel(Channel channel, String serverAddress) {
+        if (null == channel || null == serverAddress) { return; }
+        try {
+            synchronized (channelLocks.get(serverAddress)) {
+                Channel ch = channels.get(serverAddress);
+                if (null == ch) {
+                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
+                    return;
+                }
+                if (ch.compareTo(channel) == 0) {
+                    if (LOGGER.isInfoEnabled()) {
+                        LOGGER.info("return to pool, rm channel:" + channel);
+                    }
+                    destroyChannel(serverAddress, channel);
+                } else {
+                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
+                }
+            }
+        } catch (Exception exx) {
+            LOGGER.error(exx.getMessage());
+        }
+    }
+    
+    /**
+     * Destroy channel.
+     *
+     * @param serverAddress server address
+     * @param channel channel
+     */
+    void destroyChannel(String serverAddress, Channel channel) {
+        if (null == channel) { return; }
+        try {
+            if (channel.equals(channels.get(serverAddress))) {
+                channels.remove(serverAddress);
+            }
+            nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
+        } catch (Exception exx) {
+            LOGGER.error("return channel to rmPool error:" + exx.getMessage());
+        }
+    }
+    
+    /**
+     * Reconnect to remote server of current transaction service group.
+     *
+     * @param transactionServiceGroup transaction service group
+     */
+    void reconnect(String transactionServiceGroup) {
+        List<String> availList = null;
+        try {
+            availList = getAvailServerList(transactionServiceGroup);
+        } catch (Exception exx) {
+            LOGGER.error("Failed to get available servers: {}", exx.getMessage());
+        }
+        if (CollectionUtils.isEmpty(availList)) {
+            LOGGER.error("no available server to connect.");
+            return;
+        }
+        for (String serverAddress : availList) {
+            try {
+                acquireChannel(serverAddress);
+            } catch (Exception e) {
+                LOGGER.error(FrameworkErrorCode.NetConnect.getErrCode(),
+                    "can not connect to " + serverAddress + " cause:" + e.getMessage(), e);
+            }
+        }
+    }
+    
+    void invalidateObject(final String serverAddress, final Channel channel) throws Exception {
+        nettyClientKeyPool.invalidateObject(poolKeyMap.get(serverAddress), channel);
+    }
+    
+    void registerChannel(final String serverAddress, final Channel channel) {
+        if (null != channels.get(serverAddress) && channels.get(serverAddress).isActive()) {
+            return;
+        }
+        channels.put(serverAddress, channel);
+    }
+    
+    private Channel doConnect(String serverAddress) {
+        Channel channelToServer = channels.get(serverAddress);
+        if (channelToServer != null && channelToServer.isActive()) {
+            return channelToServer;
+        }
+        Channel channelFromPool;
+        try {
+            NettyPoolKey currentPoolKey = poolKeyFunction.apply(serverAddress);
+            NettyPoolKey previousPoolKey = poolKeyMap.putIfAbsent(serverAddress, currentPoolKey);
+            if (null != previousPoolKey && previousPoolKey.getMessage() instanceof RegisterRMRequest) {
+                RegisterRMRequest registerRMRequest = (RegisterRMRequest) currentPoolKey.getMessage();
+                ((RegisterRMRequest) previousPoolKey.getMessage()).setResourceIds(registerRMRequest.getResourceIds());
+            }
+            channelFromPool = nettyClientKeyPool.borrowObject(poolKeyMap.get(serverAddress));
+            channels.put(serverAddress, channelFromPool);
+        } catch (Exception exx) {
+            LOGGER.error(FrameworkErrorCode.RegisterRM.getErrCode(), "register RM failed.", exx);
+            throw new FrameworkException("can not register RM,err:" + exx.getMessage());
+        }
+        return channelFromPool;
+    }
+    
+    private List<String> getAvailServerList(String transactionServiceGroup) throws Exception {
+        List<String> availList = new ArrayList<>();
+        List<InetSocketAddress> availInetSocketAddressList = RegistryFactory.getInstance().lookup(
+            transactionServiceGroup);
+        if (!CollectionUtils.isEmpty(availInetSocketAddressList)) {
+            for (InetSocketAddress address : availInetSocketAddressList) {
+                availList.add(NetUtil.toStringAddress(address));
+            }
+        }
+        return availList;
+    }
+    
+    private Channel getExistAliveChannel(Channel rmChannel, String serverAddress) {
+        if (rmChannel.isActive()) {
+            return rmChannel;
+        } else {
+            int i = 0;
+            for (; i < NettyClientConfig.getMaxCheckAliveRetry(); i++) {
+                try {
+                    Thread.sleep(NettyClientConfig.getCheckAliveInternal());
+                } catch (InterruptedException exx) {
+                    LOGGER.error(exx.getMessage());
+                }
+                rmChannel = channels.get(serverAddress);
+                if (null == rmChannel || rmChannel.isActive()) {
+                    return rmChannel;
+                }
+            }
+            if (i == NettyClientConfig.getMaxCheckAliveRetry()) {
+                LOGGER.warn("channel " + rmChannel + " is not active after long wait, close it.");
+                releaseChannel(rmChannel, serverAddress);
+                return null;
+            }
+        }
+        return null;
+    }
+}
+
diff --git a/core/src/main/java/io/seata/core/rpc/netty/NettyPoolableFactory.java b/core/src/main/java/io/seata/core/rpc/netty/NettyPoolableFactory.java
index 9d69006f9fb758d045d82ed4cbfe42ac0b68959a..0c5c7ebea567eb2e9301f3336b9731c8fae5f1b7 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/NettyPoolableFactory.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/NettyPoolableFactory.java
@@ -15,18 +15,17 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.net.InetSocketAddress;
-
+import io.netty.channel.Channel;
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.util.NetUtil;
 import io.seata.core.protocol.RegisterRMResponse;
 import io.seata.core.protocol.RegisterTMResponse;
-
-import io.netty.channel.Channel;
 import org.apache.commons.pool.KeyedPoolableObjectFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.net.InetSocketAddress;
+
 /**
  * The type Netty key poolable factory.
  *
@@ -36,35 +35,38 @@ import org.slf4j.LoggerFactory;
 public class NettyPoolableFactory implements KeyedPoolableObjectFactory<NettyPoolKey, Channel> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(NettyPoolableFactory.class);
+    
     private final AbstractRpcRemotingClient rpcRemotingClient;
+    
+    private final RpcClientBootstrap clientBootstrap;
 
     /**
      * Instantiates a new Netty key poolable factory.
      *
      * @param rpcRemotingClient the rpc remoting client
      */
-    public NettyPoolableFactory(AbstractRpcRemotingClient rpcRemotingClient) {
+    public NettyPoolableFactory(AbstractRpcRemotingClient rpcRemotingClient,
+                                RpcClientBootstrap clientBootstrap) {
         this.rpcRemotingClient = rpcRemotingClient;
-        this.rpcRemotingClient.setChannelHandlers(rpcRemotingClient);
-        this.rpcRemotingClient.start();
+        this.clientBootstrap = clientBootstrap;
     }
 
     @Override
-    public Channel makeObject(NettyPoolKey key) throws Exception {
+    public Channel makeObject(NettyPoolKey key) {
         InetSocketAddress address = NetUtil.toInetSocketAddress(key.getAddress());
-        if (LOGGER.isInfoEnabled()) {
+            if (LOGGER.isInfoEnabled()) {
             LOGGER.info("NettyPool create channel to " + key);
         }
-        Channel tmpChannel = rpcRemotingClient.getNewChannel(address);
+        Channel tmpChannel = clientBootstrap.getNewChannel(address);
         long start = System.currentTimeMillis();
-        Object response = null;
+        Object response;
         Channel channelToServer = null;
         if (null == key.getMessage()) {
             throw new FrameworkException(
                 "register msg is null, role:" + key.getTransactionRole().name());
         }
         try {
-            response = rpcRemotingClient.sendAsyncRequestWithResponse(null, tmpChannel, key.getMessage());
+            response = rpcRemotingClient.sendAsyncRequestWithResponse(tmpChannel, key.getMessage());
             if (!isResponseSuccess(response, key.getTransactionRole())) {
                 rpcRemotingClient.onRegisterMsgFail(key.getAddress(), tmpChannel, response, key.getMessage());
             } else {
diff --git a/core/src/main/java/io/seata/core/rpc/netty/NettyServerConfig.java b/core/src/main/java/io/seata/core/rpc/netty/NettyServerConfig.java
index 37cdf06ae45affa6f287521c3b6e9b99429d70ed..e3e201e6d238496e0283b81f93408424aa10dde6 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/NettyServerConfig.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/NettyServerConfig.java
@@ -48,7 +48,7 @@ public class NettyServerConfig extends NettyBaseConfig {
     /**
      * Shutdown timeout default 1s
      */
-    private static final int DEFAULT_SHUTDOWN_TIMEOUT_SEC = 1;
+    private static final int DEFAULT_SHUTDOWN_TIMEOUT_SEC = 3;
 
     /**
      * The Server channel clazz.
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RmMessageListener.java b/core/src/main/java/io/seata/core/rpc/netty/RmMessageListener.java
index a1b81446e49840dd638a2305a201f6bc5aa51c9b..e1e3a23d260a90fea328d2bec86980eed2b8bc1f 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RmMessageListener.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RmMessageListener.java
@@ -17,6 +17,7 @@ package io.seata.core.rpc.netty;
 
 import io.seata.common.exception.FrameworkErrorCode;
 import io.seata.core.protocol.ResultCode;
+import io.seata.core.protocol.RpcMessage;
 import io.seata.core.protocol.transaction.BranchCommitRequest;
 import io.seata.core.protocol.transaction.BranchCommitResponse;
 import io.seata.core.protocol.transaction.BranchRollbackRequest;
@@ -58,18 +59,19 @@ public class RmMessageListener implements ClientMessageListener {
     }
 
     @Override
-    public void onMessage(long msgId, String serverAddress, Object msg, ClientMessageSender sender) {
+    public void onMessage(RpcMessage request, String serverAddress, ClientMessageSender sender) {
+        Object msg = request.getBody();
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("onMessage:" + msg);
         }
         if (msg instanceof BranchCommitRequest) {
-            handleBranchCommit(msgId, serverAddress, (BranchCommitRequest)msg, sender);
+            handleBranchCommit(request, serverAddress, (BranchCommitRequest)msg, sender);
         } else if (msg instanceof BranchRollbackRequest) {
-            handleBranchRollback(msgId, serverAddress, (BranchRollbackRequest)msg, sender);
+            handleBranchRollback(request, serverAddress, (BranchRollbackRequest)msg, sender);
         }
     }
 
-    private void handleBranchRollback(long msgId, String serverAddress,
+    private void handleBranchRollback(RpcMessage request, String serverAddress,
                                       BranchRollbackRequest branchRollbackRequest,
                                       ClientMessageSender sender) {
         BranchRollbackResponse resultMessage = null;
@@ -78,20 +80,20 @@ public class RmMessageListener implements ClientMessageListener {
             LOGGER.debug("branch rollback result:" + resultMessage);
         }
         try {
-            sender.sendResponse(msgId, serverAddress, resultMessage);
+            sender.sendResponse(request, serverAddress, resultMessage);
         } catch (Throwable throwable) {
             LOGGER.error("", "send response error", throwable);
         }
     }
 
-    private void handleBranchCommit(long msgId, String serverAddress,
+    private void handleBranchCommit(RpcMessage request, String serverAddress,
                                     BranchCommitRequest branchCommitRequest,
                                     ClientMessageSender sender) {
 
         BranchCommitResponse resultMessage = null;
         try {
             resultMessage = (BranchCommitResponse)handler.onRequest(branchCommitRequest, null);
-            sender.sendResponse(msgId, serverAddress, resultMessage);
+            sender.sendResponse(request, serverAddress, resultMessage);
         } catch (Exception e) {
             LOGGER.error(FrameworkErrorCode.NetOnMessage.getErrCode(), e.getMessage(), e);
             if (resultMessage == null) {
@@ -99,7 +101,7 @@ public class RmMessageListener implements ClientMessageListener {
             }
             resultMessage.setResultCode(ResultCode.Failed);
             resultMessage.setMsg(e.getMessage());
-            sender.sendResponse(msgId, serverAddress, resultMessage);
+            sender.sendResponse(request, serverAddress, resultMessage);
         }
     }
 }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RmRpcClient.java b/core/src/main/java/io/seata/core/rpc/netty/RmRpcClient.java
index 3f68380574dfb16cfb8dc7d0cbdecbdd888a1438..dc9e9deed141a5c1a4ba653bbd8c6f94a7d3fa53 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RmRpcClient.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RmRpcClient.java
@@ -15,87 +15,55 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.timeout.IdleStateEvent;
 import io.netty.util.concurrent.EventExecutorGroup;
 import io.seata.common.exception.FrameworkErrorCode;
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.thread.NamedThreadFactory;
-import io.seata.common.util.NetUtil;
 import io.seata.core.model.Resource;
 import io.seata.core.model.ResourceManager;
 import io.seata.core.protocol.AbstractMessage;
-import io.seata.core.protocol.HeartbeatMessage;
 import io.seata.core.protocol.RegisterRMRequest;
 import io.seata.core.protocol.RegisterRMResponse;
 import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool.Config;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
+
 import static io.seata.common.Constants.DBKEYS_SPLIT_CHAR;
 
 /**
  * The type Rm rpc client.
  *
  * @author jimin.jm @alibaba-inc.com
+ * @author zhaojun
  * @date 2018 /10/10
  */
 @Sharable
 public final class RmRpcClient extends AbstractRpcRemotingClient {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(RmRpcClient.class);
-
     private ResourceManager resourceManager;
-
-    private String applicationId;
-
-    private String transactionServiceGroup;
-
     private static volatile RmRpcClient instance;
-    private final ConcurrentMap<String, Object> channelLocks = new ConcurrentHashMap<String, Object>();
-    private final ConcurrentMap<String, NettyPoolKey> poolKeyMap = new ConcurrentHashMap<String, NettyPoolKey>();
-    private final ConcurrentMap<String, Channel> channels = new ConcurrentHashMap<>();
     private String customerKeys;
     private final AtomicBoolean initialized = new AtomicBoolean(false);
-    private static final int MAX_MERGE_SEND_THREAD = 1;
     private static final long KEEP_ALIVE_TIME = Integer.MAX_VALUE;
     private static final int MAX_QUEUE_SIZE = 20000;
-    private static final int SCHEDULE_INTERVAL_MILLS = 5;
-    private static final String MERGE_THREAD_PREFIX = "rpcMergeMessageSend";
-    private final NettyClientConfig rmClientConfig;
-
-    private RmRpcClient(NettyClientConfig nettyClientConfig) {
-        super(nettyClientConfig);
-        this.rmClientConfig = nettyClientConfig;
-    }
-
+    private String applicationId;
+    private String transactionServiceGroup;
+    
     private RmRpcClient(NettyClientConfig nettyClientConfig, EventExecutorGroup eventExecutorGroup,
                         ThreadPoolExecutor messageExecutor) {
-        super(nettyClientConfig, eventExecutorGroup, messageExecutor);
-        this.rmClientConfig = nettyClientConfig;
-    }
-
-    /**
-     * Sets resource manager.
-     *
-     * @param resourceManager the resource manager
-     */
-    public void setResourceManager(ResourceManager resourceManager) {
-        this.resourceManager = resourceManager;
+        super(nettyClientConfig, eventExecutorGroup, messageExecutor, TransactionRole.RMROLE);
     }
 
     /**
@@ -122,39 +90,20 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
             synchronized (RmRpcClient.class) {
                 if (null == instance) {
                     NettyClientConfig nettyClientConfig = new NettyClientConfig();
-                    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
+                    final ThreadPoolExecutor messageExecutor = new ThreadPoolExecutor(
                         nettyClientConfig.getClientWorkerThreads(), nettyClientConfig.getClientWorkerThreads(),
                         KEEP_ALIVE_TIME, TimeUnit.SECONDS,
-                        new LinkedBlockingQueue(MAX_QUEUE_SIZE),
+                        new LinkedBlockingQueue<>(MAX_QUEUE_SIZE),
                         new NamedThreadFactory(nettyClientConfig.getRmDispatchThreadPrefix(),
                             nettyClientConfig.getClientWorkerThreads()),
                         new ThreadPoolExecutor.CallerRunsPolicy());
-                    instance = new RmRpcClient(nettyClientConfig, null, threadPoolExecutor);
+                    instance = new RmRpcClient(nettyClientConfig, null, messageExecutor);
                 }
             }
         }
         return instance;
     }
-
-    @Override
-    public void init() {
-        if (initialized.compareAndSet(false, true)) {
-            super.init();
-            timerExecutor.scheduleAtFixedRate(new Runnable() {
-                @Override
-                public void run() {
-                    reconnect(transactionServiceGroup);
-                }
-            }, SCHEDULE_INTERVAL_MILLS, SCHEDULE_INTERVAL_MILLS, TimeUnit.SECONDS);
-            ExecutorService mergeSendExecutorService = new ThreadPoolExecutor(MAX_MERGE_SEND_THREAD,
-                MAX_MERGE_SEND_THREAD,
-                KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
-                new LinkedBlockingQueue<Runnable>(),
-                new NamedThreadFactory(getThreadPrefix(MERGE_THREAD_PREFIX), MAX_MERGE_SEND_THREAD));
-            mergeSendExecutorService.submit(new MergedSendRunnable());
-        }
-    }
-
+    
     /**
      * Sets application id.
      *
@@ -163,7 +112,7 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
     public void setApplicationId(String applicationId) {
         this.applicationId = applicationId;
     }
-
+    
     /**
      * Sets transaction service group.
      *
@@ -172,206 +121,97 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
     public void setTransactionServiceGroup(String transactionServiceGroup) {
         this.transactionServiceGroup = transactionServiceGroup;
     }
-
-    @Override
-    protected Config getNettyPoolConfig() {
-        Config poolConfig = new Config();
-        poolConfig.maxActive = rmClientConfig.getMaxPoolActive();
-        poolConfig.minIdle = rmClientConfig.getMinPoolIdle();
-        poolConfig.maxWait = rmClientConfig.getMaxAcquireConnMills();
-        poolConfig.testOnBorrow = rmClientConfig.isPoolTestBorrow();
-        poolConfig.testOnReturn = rmClientConfig.isPoolTestReturn();
-        poolConfig.lifo = rmClientConfig.isPoolLifo();
-        return poolConfig;
+    
+    /**
+     * Sets resource manager.
+     *
+     * @param resourceManager the resource manager
+     */
+    public void setResourceManager(ResourceManager resourceManager) {
+        this.resourceManager = resourceManager;
     }
-
-    @Override
-    protected NettyPoolKey.TransactionRole getTransactionRole() {
-        return TransactionRole.RMROLE;
+    
+    /**
+     * Gets customer keys.
+     *
+     * @return the customer keys
+     */
+    public String getCustomerKeys() {
+        return customerKeys;
     }
-
-    @Override
-    public Object sendMsgWithResponse(Object msg, long timeout) throws TimeoutException {
-        String validAddress = loadBalance(transactionServiceGroup);
-        Channel acquireChannel = connect(validAddress);
-        return super.sendAsyncRequestWithResponse(validAddress, acquireChannel, msg, timeout);
+    
+    /**
+     * Sets customer keys.
+     *
+     * @param customerKeys the customer keys
+     */
+    public void setCustomerKeys(String customerKeys) {
+        this.customerKeys = customerKeys;
     }
-
+    
     @Override
-    public Object sendMsgWithResponse(String serverAddress, Object msg, long timeout) throws TimeoutException {
-        return super.sendAsyncRequestWithResponse(serverAddress, connect(serverAddress), msg, timeout);
+    public void init() {
+        if (initialized.compareAndSet(false, true)) {
+            super.init();
+        }
     }
-
+    
     @Override
-    public Object sendMsgWithResponse(Object msg) throws TimeoutException {
-        return sendMsgWithResponse(msg, NettyClientConfig.getRpcRequestTimeout());
+    public void destroy() {
+        super.destroy();
+        initialized.getAndSet(false);
+        instance = null;
     }
-
+    
     @Override
-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
-        if (evt instanceof IdleStateEvent) {
-            IdleStateEvent idleStateEvent = (IdleStateEvent)evt;
-            if (idleStateEvent == IdleStateEvent.READER_IDLE_STATE_EVENT) {
-                if (LOGGER.isInfoEnabled()) {
-                    LOGGER.info("RmRpcClient channel" + ctx.channel() + " idle.");
-                }
-                try {
-                    String serverAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
-                    nettyClientKeyPool.invalidateObject(poolKeyMap.get(serverAddress), ctx.channel());
-                } catch (Exception exx) {
-                    LOGGER.error(exx.getMessage());
-                } finally {
-                    releaseChannel(ctx.channel(), getAddressFromContext(ctx));
-                }
-            }
-            if (idleStateEvent == IdleStateEvent.WRITER_IDLE_STATE_EVENT) {
-                try {
-                    sendRequest(ctx.channel(), HeartbeatMessage.PING);
-                } catch (Throwable throwable) {
-                    LOGGER.error("", "send request error", throwable);
-                }
+    protected Function<String, NettyPoolKey> getPoolKeyFunction() {
+        return (serverAddress) -> {
+            String resourceIds = customerKeys == null ? getMergedResourceKeys() : customerKeys;
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info("RM will register :" + resourceIds);
             }
-        }
+            RegisterRMRequest message = new RegisterRMRequest(applicationId, transactionServiceGroup);
+            message.setResourceIds(resourceIds);
+            return new NettyPoolKey(NettyPoolKey.TransactionRole.RMROLE, serverAddress, message);
+        };
     }
-
+    
     @Override
-    protected void releaseChannel(Channel channel, String serverAddress) {
-        if (null == channel || null == serverAddress) { return; }
-        Object connectLock = channelLocks.get(serverAddress);
-        try {
-            synchronized (connectLock) {
-                Channel ch = channels.get(serverAddress);
-                if (null == ch) {
-                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-                    return;
-                }
-                if (ch.compareTo(channel) == 0) {
-                    if (LOGGER.isInfoEnabled()) {
-                        LOGGER.info("return to pool, rm channel:" + channel);
-                    }
-                    destroyChannel(serverAddress, channel);
-                } else {
-                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-                }
-            }
-        } catch (Exception exx) {
-            LOGGER.error(exx.getMessage());
-        }
+    protected String getTransactionServiceGroup() {
+        return transactionServiceGroup;
     }
-
+    
     @Override
-    protected Channel connect(String serverAddress) {
-        Channel channelToServer = channels.get(serverAddress);
-        if (channelToServer != null) {
-            channelToServer = getExistAliveChannel(channelToServer, serverAddress);
-            if (null != channelToServer) {
-                return channelToServer;
-            }
-        }
+    public void onRegisterMsgSuccess(String serverAddress, Channel channel, Object response,
+                                     AbstractMessage requestMessage) {
         if (LOGGER.isInfoEnabled()) {
-            LOGGER.info("will connect to " + serverAddress);
-        }
-        channelLocks.putIfAbsent(serverAddress, new Object());
-        Object connectLock = channelLocks.get(serverAddress);
-        synchronized (connectLock) {
-            Channel channel = doConnect(serverAddress);
-            return channel;
-        }
-    }
-
-    /**
-     * Connect channel.
-     *
-     * @param serverAddress the server address
-     * @return the channel
-     */
-    private Channel doConnect(String serverAddress) {
-        Channel channelToServer = channels.get(serverAddress);
-        if (channelToServer != null && channelToServer.isActive()) {
-            return channelToServer;
-        }
-        Channel channelFromPool = null;
-        try {
-            String resourceIds = customerKeys == null ? getMergedResourceKeys(resourceManager) : customerKeys;
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("RM will register :" + resourceIds);
-            }
-            RegisterRMRequest message = null;
-            if (null == poolKeyMap.get(serverAddress)) {
-                message = new RegisterRMRequest(applicationId, transactionServiceGroup);
-                message.setResourceIds(resourceIds);
-                poolKeyMap.putIfAbsent(serverAddress,
-                    new NettyPoolKey(getTransactionRole(), serverAddress, message));
-            } else {
-                message = (RegisterRMRequest)poolKeyMap.get(serverAddress).getMessage();
-                message.setResourceIds(resourceIds);
-            }
-            channelFromPool = nettyClientKeyPool.borrowObject(poolKeyMap.get(serverAddress));
-        } catch (Exception exx) {
-            LOGGER.error(FrameworkErrorCode.RegisterRM.getErrCode(), "register RM failed.", exx);
-            throw new FrameworkException("can not register RM,err:" + exx.getMessage());
+            LOGGER.info(
+                "register RM success. server version:" + ((RegisterRMResponse)response).getVersion()
+                    + ",channel:" + channel);
         }
-        return channelFromPool;
-    }
-
-    private Channel getExistAliveChannel(Channel rmChannel, String serverAddress) {
-        if (rmChannel.isActive()) {
-            return rmChannel;
-        } else {
-            int i = 0;
-            for (; i < NettyClientConfig.getMaxCheckAliveRetry(); i++) {
-                try {
-                    Thread.sleep(NettyClientConfig.getCheckAliveInternal());
-                } catch (InterruptedException exx) {
-                    LOGGER.error(exx.getMessage());
-                }
-                rmChannel = channels.get(serverAddress);
-                if (null == rmChannel || rmChannel.isActive()) {
-                    return rmChannel;
+        if (customerKeys == null) {
+            getClientChannelManager().registerChannel(serverAddress, channel);
+            String dbKey = getMergedResourceKeys();
+            RegisterRMRequest message = (RegisterRMRequest)requestMessage;
+            if (message.getResourceIds() != null) {
+                if (!message.getResourceIds().equals(dbKey)) {
+                    sendRegisterMessage(serverAddress, channel, dbKey);
                 }
             }
-            if (i == NettyClientConfig.getMaxCheckAliveRetry()) {
-                LOGGER.warn("channel " + rmChannel + " is not active after long wait, close it.");
-                releaseChannel(rmChannel, serverAddress);
-                return null;
-            }
         }
-        return null;
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-        LOGGER.error(FrameworkErrorCode.ExceptionCaught.getErrCode(),
-            NetUtil.toStringAddress(ctx.channel().remoteAddress()) + "connect exception. " + cause.getMessage(),
-            cause);
-        releaseChannel(ctx.channel(), getAddressFromChannel(ctx.channel()));
-        if (LOGGER.isInfoEnabled()) {
-            LOGGER.info("remove exception rm channel:" + ctx.channel());
-        }
-        super.exceptionCaught(ctx, cause);
-    }
+    public void onRegisterMsgFail(String serverAddress, Channel channel, Object response,
+                                  AbstractMessage requestMessage) {
 
-    private void sendRegisterMessage(String serverAddress, Channel channel, String dbKey) {
-        RegisterRMRequest message = new RegisterRMRequest(applicationId,
-            transactionServiceGroup);
-        message.setResourceIds(dbKey);
-        try {
-            super.sendAsyncRequestWithoutResponse(null, channel, message);
-        } catch (FrameworkException e) {
-            if (e.getErrcode() == FrameworkErrorCode.ChannelIsNotWritable
-                && serverAddress != null) {
-                releaseChannel(channel, serverAddress);
-                if (LOGGER.isInfoEnabled()) {
-                    LOGGER.info("remove channel:" + channel);
-                }
-            } else {
-                LOGGER.error("", "register failed", e);
-            }
-        } catch (TimeoutException e) {
-            LOGGER.error(e.getMessage());
+        if (response instanceof RegisterRMResponse && LOGGER.isInfoEnabled()) {
+            LOGGER.info(
+                "register RM failed. server version:" + ((RegisterRMResponse)response).getVersion());
         }
+        throw new FrameworkException("register RM failed.");
     }
-
+    
     /**
      * Register new db key.
      *
@@ -382,12 +222,12 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
         if (LOGGER.isInfoEnabled()) {
             LOGGER.info("register to RM resourceId:" + resourceId);
         }
-        if (channels.isEmpty()) {
-            reconnect(transactionServiceGroup);
+        if (getClientChannelManager().getChannels().isEmpty()) {
+            getClientChannelManager().reconnect(transactionServiceGroup);
             return;
         }
-        synchronized (channels) {
-            for (Map.Entry<String, Channel> entry : channels.entrySet()) {
+        synchronized (getClientChannelManager().getChannels()) {
+            for (Map.Entry<String, Channel> entry : getClientChannelManager().getChannels().entrySet()) {
                 String serverAddress = entry.getKey();
                 Channel rmChannel = entry.getValue();
                 if (LOGGER.isInfoEnabled()) {
@@ -397,68 +237,32 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
             }
         }
     }
-
-    @Override
-    public void sendResponse(long msgId, String serverAddress, Object msg) {
-        if (LOGGER.isInfoEnabled()) {
-            LOGGER.info("RmRpcClient sendResponse " + msg);
-        }
-        super.sendResponse(msgId, connect(serverAddress), msg);
-    }
-
-    /**
-     * Gets customer keys.
-     *
-     * @return the customer keys
-     */
-    public String getCustomerKeys() {
-        return customerKeys;
-    }
-
-    /**
-     * Sets customer keys.
-     *
-     * @param customerKeys the customer keys
-     */
-    public void setCustomerKeys(String customerKeys) {
-        this.customerKeys = customerKeys;
-    }
-
-    @Override
-    public void onRegisterMsgSuccess(String serverAddress, Channel channel, Object response,
-                                     AbstractMessage requestMessage) {
-
-        if (LOGGER.isInfoEnabled()) {
-            LOGGER.info(
-                "register RM success. server version:" + ((RegisterRMResponse)response).getVersion()
-                    + ",channel:" + channel);
-        }
-        if (customerKeys == null) {
-            synchronized (channels) {
-                channels.put(serverAddress, channel);
-            }
-            String dbKey = getMergedResourceKeys(resourceManager);
-            RegisterRMRequest message = (RegisterRMRequest)requestMessage;
-            if (message.getResourceIds() != null) {
-                if (!message.getResourceIds().equals(dbKey)) {
-                    sendRegisterMessage(serverAddress, channel, dbKey);
+    
+    private void sendRegisterMessage(String serverAddress, Channel channel, String dbKey) {
+        RegisterRMRequest message = new RegisterRMRequest(applicationId, transactionServiceGroup);
+        message.setResourceIds(dbKey);
+        try {
+            super.sendAsyncRequestWithoutResponse(channel, message);
+        } catch (FrameworkException e) {
+            if (e.getErrcode() == FrameworkErrorCode.ChannelIsNotWritable
+                && serverAddress != null) {
+                getClientChannelManager().releaseChannel(channel, serverAddress);
+                if (LOGGER.isInfoEnabled()) {
+                    LOGGER.info("remove channel:" + channel);
                 }
+            } else {
+                LOGGER.error("", "register failed", e);
             }
+        } catch (TimeoutException e) {
+            LOGGER.error(e.getMessage());
         }
     }
-
-    /**
-     * Gets merged resource keys.
-     *
-     * @param resourceManager the resource manager
-     * @return the merged resource keys
-     */
-    public String getMergedResourceKeys(ResourceManager resourceManager) {
-        //TODO
+    
+    private String getMergedResourceKeys() {
         Map<String, Resource> managedResources = resourceManager.getManagedResources();
         Set<String> resourceIds = managedResources.keySet();
         if (!resourceIds.isEmpty()) {
-            StringBuffer sb = new StringBuffer();
+            StringBuilder sb = new StringBuilder();
             boolean first = true;
             for (String resourceId : resourceIds) {
                 if (first) {
@@ -472,29 +276,4 @@ public final class RmRpcClient extends AbstractRpcRemotingClient {
         }
         return null;
     }
-
-    @Override
-    public void onRegisterMsgFail(String serverAddress, Channel channel, Object response,
-                                  AbstractMessage requestMessage) {
-
-        if (response instanceof RegisterRMResponse && LOGGER.isInfoEnabled()) {
-            LOGGER.info(
-                "register RM failed. server version:" + ((RegisterRMResponse)response).getVersion());
-        }
-        throw new FrameworkException("register RM failed.");
-    }
-
-    @Override
-    public void destroyChannel(String serverAddress, Channel channel) {
-        if (null == channel) { return; }
-        try {
-            if (channel.equals(channels.get(serverAddress))) {
-                channels.remove(serverAddress);
-            }
-            nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-        } catch (Exception exx) {
-            LOGGER.error("return channel to rmPool error:" + exx.getMessage());
-        }
-    }
-
 }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RpcClientBootstrap.java b/core/src/main/java/io/seata/core/rpc/netty/RpcClientBootstrap.java
new file mode 100644
index 0000000000000000000000000000000000000000..ec596a19f045eb3c91c9c2e63d1b202e95319067
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/netty/RpcClientBootstrap.java
@@ -0,0 +1,209 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.EpollChannelOption;
+import io.netty.channel.epoll.EpollMode;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.pool.AbstractChannelPoolMap;
+import io.netty.channel.pool.ChannelHealthChecker;
+import io.netty.channel.pool.FixedChannelPool;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.timeout.IdleStateHandler;
+import io.netty.util.concurrent.DefaultEventExecutorGroup;
+import io.netty.util.concurrent.EventExecutorGroup;
+import io.netty.util.internal.PlatformDependent;
+import io.seata.common.exception.FrameworkException;
+import io.seata.common.thread.NamedThreadFactory;
+import io.seata.core.rpc.RemotingClient;
+import io.seata.core.rpc.netty.v1.ProtocolV1Decoder;
+import io.seata.core.rpc.netty.v1.ProtocolV1Encoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Rpc client.
+ *
+ * @author jimin.jm @alibaba-inc.com
+ * @author zhaojun
+ */
+public class RpcClientBootstrap implements RemotingClient {
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRpcRemotingClient.class);
+    private final NettyClientConfig nettyClientConfig;
+    private final Bootstrap bootstrap = new Bootstrap();
+    private final EventLoopGroup eventLoopGroupWorker;
+    private EventExecutorGroup defaultEventExecutorGroup;
+    private AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool> clientChannelPool;
+    private final AtomicBoolean initialized = new AtomicBoolean(false);
+    private static final String THREAD_PREFIX_SPLIT_CHAR = "_";
+    private final ChannelHandler channelHandler;
+    private final NettyPoolKey.TransactionRole transactionRole;
+    
+    public RpcClientBootstrap(NettyClientConfig nettyClientConfig, final EventExecutorGroup eventExecutorGroup,
+                              ChannelHandler channelHandler, NettyPoolKey.TransactionRole transactionRole) {
+        if (null == nettyClientConfig) {
+            nettyClientConfig = new NettyClientConfig();
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info("use default netty client config.");
+            }
+        }
+        this.nettyClientConfig = nettyClientConfig;
+        int selectorThreadSizeThreadSize = this.nettyClientConfig.getClientSelectorThreadSize();
+        this.transactionRole = transactionRole;
+        this.eventLoopGroupWorker = new NioEventLoopGroup(selectorThreadSizeThreadSize,
+            new NamedThreadFactory(getThreadPrefix(this.nettyClientConfig.getClientSelectorThreadPrefix()),
+                selectorThreadSizeThreadSize));
+        this.defaultEventExecutorGroup = eventExecutorGroup;
+        this.channelHandler = channelHandler;
+    }
+    
+    @Override
+    public void start() {
+        if (this.defaultEventExecutorGroup == null) {
+            this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(nettyClientConfig.getClientWorkerThreads(),
+                new NamedThreadFactory(getThreadPrefix(nettyClientConfig.getClientWorkerThreadPrefix()),
+                    nettyClientConfig.getClientWorkerThreads()));
+        }
+        this.bootstrap.group(this.eventLoopGroupWorker).channel(
+            nettyClientConfig.getClientChannelClazz()).option(
+            ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true).option(
+            ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyClientConfig.getConnectTimeoutMillis()).option(
+            ChannelOption.SO_SNDBUF, nettyClientConfig.getClientSocketSndBufSize()).option(ChannelOption.SO_RCVBUF,
+            nettyClientConfig.getClientSocketRcvBufSize());
+    
+        if (nettyClientConfig.enableNative()) {
+            if (PlatformDependent.isOsx()) {
+                if (LOGGER.isInfoEnabled()) {
+                    LOGGER.info("client run on macOS");
+                }
+            } else {
+                bootstrap.option(EpollChannelOption.EPOLL_MODE, EpollMode.EDGE_TRIGGERED)
+                    .option(EpollChannelOption.TCP_QUICKACK, true);
+            }
+        }
+        if (nettyClientConfig.isUseConnPool()) {
+            clientChannelPool = new AbstractChannelPoolMap<InetSocketAddress, FixedChannelPool>() {
+                @Override
+                protected FixedChannelPool newPool(InetSocketAddress key) {
+                    return new FixedChannelPool(
+                        bootstrap.remoteAddress(key),
+                        new DefaultChannelPoolHandler() {
+                            @Override
+                            public void channelCreated(Channel ch) throws Exception {
+                                super.channelCreated(ch);
+                                final ChannelPipeline pipeline = ch.pipeline();
+                                pipeline.addLast(defaultEventExecutorGroup,
+                                    new IdleStateHandler(nettyClientConfig.getChannelMaxReadIdleSeconds(),
+                                        nettyClientConfig.getChannelMaxWriteIdleSeconds(),
+                                        nettyClientConfig.getChannelMaxAllIdleSeconds()));
+                                pipeline.addLast(defaultEventExecutorGroup, new RpcClientHandler());
+                            }
+                        },
+                        ChannelHealthChecker.ACTIVE,
+                        FixedChannelPool.AcquireTimeoutAction.FAIL,
+                        nettyClientConfig.getMaxAcquireConnMills(),
+                        nettyClientConfig.getPerHostMaxConn(),
+                        nettyClientConfig.getPendingConnSize(),
+                        false
+                    );
+                }
+            };
+        } else {
+            bootstrap.handler(
+                new ChannelInitializer<SocketChannel>() {
+                
+                    @Override
+                    public void initChannel(SocketChannel ch) {
+                        ChannelPipeline pipeline = ch.pipeline();
+                        pipeline.addLast(
+                            new IdleStateHandler(nettyClientConfig.getChannelMaxReadIdleSeconds(),
+                                nettyClientConfig.getChannelMaxWriteIdleSeconds(),
+                                nettyClientConfig.getChannelMaxAllIdleSeconds()))
+                                .addLast(new ProtocolV1Decoder())
+                                .addLast(new ProtocolV1Encoder());
+                        if (null != channelHandler) {
+                            ch.pipeline().addLast(channelHandler);
+                        }
+                    }
+                });
+        }
+        if (initialized.compareAndSet(false, true) && LOGGER.isInfoEnabled()) {
+            LOGGER.info("RpcClientBootstrap has started");
+        }
+    }
+    
+    @Override
+    public void shutdown() {
+        try {
+            if (null != clientChannelPool) {
+                clientChannelPool.close();
+            }
+            this.eventLoopGroupWorker.shutdownGracefully();
+            if (this.defaultEventExecutorGroup != null) {
+                this.defaultEventExecutorGroup.shutdownGracefully();
+            }
+        } catch (Exception exx) {
+            LOGGER.error("Failed to shutdown: {}", exx.getMessage());
+        }
+    }
+    
+    /**
+     * Gets new channel.
+     *
+     * @param address the address
+     * @return the new channel
+     */
+    public Channel getNewChannel(InetSocketAddress address) {
+        Channel channel;
+        ChannelFuture f = this.bootstrap.connect(address);
+        try {
+            f.await(this.nettyClientConfig.getConnectTimeoutMillis(), TimeUnit.MILLISECONDS);
+            if (f.isCancelled()) {
+                throw new FrameworkException(f.cause(), "connect cancelled, can not connect to services-server.");
+            } else if (!f.isSuccess()) {
+                throw new FrameworkException(f.cause(), "connect failed, can not connect to services-server.");
+            } else {
+                channel = f.channel();
+            }
+        } catch (Exception e) {
+            throw new FrameworkException(e, "can not connect to services-server.");
+        }
+        return channel;
+    }
+    
+    /**
+     * Gets thread prefix.
+     *
+     * @param threadPrefix the thread prefix
+     * @return the thread prefix
+     */
+    private String getThreadPrefix(String threadPrefix) {
+        return threadPrefix + THREAD_PREFIX_SPLIT_CHAR + transactionRole.name();
+    }
+}
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RpcServer.java b/core/src/main/java/io/seata/core/rpc/netty/RpcServer.java
index 6f8de79c54622273d79286796cc1dd1d71e1d526..77874d2d17f3cae2b2b9bdbb1f308ae280a2560f 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RpcServer.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RpcServer.java
@@ -15,9 +15,11 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeoutException;
-
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
 import io.seata.common.util.NetUtil;
 import io.seata.core.protocol.HeartbeatMessage;
 import io.seata.core.protocol.RegisterRMRequest;
@@ -29,15 +31,12 @@ import io.seata.core.rpc.RpcContext;
 import io.seata.core.rpc.ServerMessageListener;
 import io.seata.core.rpc.ServerMessageSender;
 import io.seata.core.rpc.TransactionMessageHandler;
-
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.timeout.IdleState;
-import io.netty.handler.timeout.IdleStateEvent;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeoutException;
+
 /**
  * The type Abstract rpc server.
  *
@@ -181,18 +180,18 @@ public class RpcServer extends AbstractRpcRemotingServer implements ServerMessag
      * Send response.
      * rm reg,rpc reg,inner response
      *
-     * @param msgId   the msg id
+     * @param request the request
      * @param channel the channel
      * @param msg     the msg
      */
     @Override
-    public void sendResponse(long msgId, Channel channel, Object msg) {
+    public void sendResponse(RpcMessage request, Channel channel, Object msg) {
         Channel clientChannel = channel;
         if (!(msg instanceof HeartbeatMessage)) {
             clientChannel = ChannelManager.getSameClientChannel(channel);
         }
         if (clientChannel != null) {
-            super.sendResponse(msgId, clientChannel, msg);
+            super.sendResponse(request, clientChannel, msg);
         } else {
             throw new RuntimeException("channel is error. channel:" + clientChannel);
         }
@@ -239,18 +238,18 @@ public class RpcServer extends AbstractRpcRemotingServer implements ServerMessag
     /**
      * Dispatch.
      *
-     * @param msgId the msg id
+     * @param request the request
      * @param ctx   the ctx
-     * @param msg   the msg
      */
     @Override
-    public void dispatch(long msgId, ChannelHandlerContext ctx, Object msg) {
+    public void dispatch(RpcMessage request, ChannelHandlerContext ctx) {
+        Object msg = request.getBody();
         if (msg instanceof RegisterRMRequest) {
-            serverMessageListener.onRegRmMessage(msgId, ctx, (RegisterRMRequest)msg, this,
+            serverMessageListener.onRegRmMessage(request, ctx, this,
                 checkAuthHandler);
         } else {
             if (ChannelManager.isRegistered(ctx.channel())) {
-                serverMessageListener.onTrxMessage(msgId, ctx, msg, this);
+                serverMessageListener.onTrxMessage(request, ctx, this);
             } else {
                 try {
                     closeChannelHandlerContext(ctx);
@@ -308,17 +307,14 @@ public class RpcServer extends AbstractRpcRemotingServer implements ServerMessag
     @Override
     public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
         if (msg instanceof RpcMessage) {
-            RpcMessage rpcMessage = (RpcMessage)msg;
+            RpcMessage rpcMessage = (RpcMessage) msg;
             debugLog("read:" + rpcMessage.getBody().toString());
             if (rpcMessage.getBody() instanceof RegisterTMRequest) {
-                RegisterTMRequest request
-                    = (RegisterTMRequest)rpcMessage
-                    .getBody();
-                serverMessageListener.onRegTmMessage(rpcMessage.getId(), ctx, request, this, checkAuthHandler);
+                serverMessageListener.onRegTmMessage(rpcMessage, ctx, this, checkAuthHandler);
                 return;
             }
             if (rpcMessage.getBody() == HeartbeatMessage.PING) {
-                serverMessageListener.onCheckMessage(rpcMessage.getId(), ctx, this);
+                serverMessageListener.onCheckMessage(rpcMessage, ctx, this);
                 return;
             }
         }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/TmRpcClient.java b/core/src/main/java/io/seata/core/rpc/netty/TmRpcClient.java
index cf146db41574d2376608d97d5328c0214dfb22dc..17fae302edcc88475b4574ee453935f43210b8bc 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/TmRpcClient.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/TmRpcClient.java
@@ -17,61 +17,43 @@ package io.seata.core.rpc.netty;
 
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.timeout.IdleState;
-import io.netty.handler.timeout.IdleStateEvent;
 import io.netty.util.concurrent.EventExecutorGroup;
-import io.seata.common.exception.FrameworkErrorCode;
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.thread.NamedThreadFactory;
 import io.seata.common.thread.RejectedPolicies;
-import io.seata.common.util.NetUtil;
 import io.seata.config.Configuration;
 import io.seata.config.ConfigurationFactory;
 import io.seata.core.constants.ConfigurationKeys;
 import io.seata.core.protocol.AbstractMessage;
-import io.seata.core.protocol.HeartbeatMessage;
 import io.seata.core.protocol.RegisterTMRequest;
 import io.seata.core.protocol.RegisterTMResponse;
-import io.seata.core.protocol.ResultCode;
-import io.seata.core.protocol.transaction.GlobalBeginResponse;
-import org.apache.commons.pool.impl.GenericKeyedObjectPool.Config;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
 
 /**
  * The type Rpc client.
  *
  * @author jimin.jm @alibaba-inc.com
+ * @author zhaojun
  * @date 2018 /10/23
  */
 @Sharable
 public final class TmRpcClient extends AbstractRpcRemotingClient {
     private static final Logger LOGGER = LoggerFactory.getLogger(TmRpcClient.class);
     private static volatile TmRpcClient instance;
-    private static final int MAX_MERGE_SEND_THREAD = 1;
-    private final ConcurrentMap<String, Object> channelLocks = new ConcurrentHashMap<String, Object>();
-    private final ConcurrentMap<String, Channel> channels = new ConcurrentHashMap<String, Channel>();
     private static final Configuration CONFIG = ConfigurationFactory.getInstance();
     private static final long KEEP_ALIVE_TIME = Integer.MAX_VALUE;
     private static final int MAX_QUEUE_SIZE = 2000;
-    private static final String MERGE_THREAD_PREFIX = "rpcMergeMessageSend";
-    private static final int SCHEDULE_INTERVAL_MILLS = 5;
     private final AtomicBoolean initialized = new AtomicBoolean(false);
     private String applicationId;
     private String transactionServiceGroup;
-    private final NettyClientConfig tmClientConfig;
-    private final ConcurrentMap<String, NettyPoolKey> poolKeyMap
-        = new ConcurrentHashMap<String, NettyPoolKey>();
+    
     /**
      * The constant enableDegrade.
      */
@@ -80,8 +62,7 @@ public final class TmRpcClient extends AbstractRpcRemotingClient {
     private TmRpcClient(NettyClientConfig nettyClientConfig,
                         EventExecutorGroup eventExecutorGroup,
                         ThreadPoolExecutor messageExecutor) {
-        super(nettyClientConfig, eventExecutorGroup, messageExecutor);
-        this.tmClientConfig = nettyClientConfig;
+        super(nettyClientConfig, eventExecutorGroup, messageExecutor, NettyPoolKey.TransactionRole.TMROLE);
     }
 
     /**
@@ -108,250 +89,29 @@ public final class TmRpcClient extends AbstractRpcRemotingClient {
             synchronized (TmRpcClient.class) {
                 if (null == instance) {
                     NettyClientConfig nettyClientConfig = new NettyClientConfig();
-                    final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
+                    final ThreadPoolExecutor messageExecutor = new ThreadPoolExecutor(
                         nettyClientConfig.getClientWorkerThreads(), nettyClientConfig.getClientWorkerThreads(),
                         KEEP_ALIVE_TIME, TimeUnit.SECONDS,
-                        new LinkedBlockingQueue(MAX_QUEUE_SIZE),
+                        new LinkedBlockingQueue<>(MAX_QUEUE_SIZE),
                         new NamedThreadFactory(nettyClientConfig.getTmDispatchThreadPrefix(),
                             nettyClientConfig.getClientWorkerThreads()),
                         RejectedPolicies.runsOldestTaskPolicy());
-                    instance = new TmRpcClient(nettyClientConfig, null, threadPoolExecutor);
+                    instance = new TmRpcClient(nettyClientConfig, null, messageExecutor);
                 }
             }
         }
         return instance;
     }
-
-    @Override
-    public void init() {
-        if (initialized.compareAndSet(false, true)) {
-            init(SCHEDULE_INTERVAL_MILLS, SCHEDULE_INTERVAL_MILLS);
-        }
-    }
-
-    private void initVars() {
-        enableDegrade = CONFIG.getBoolean(ConfigurationKeys.SERVICE_PREFIX + ConfigurationKeys.ENABLE_DEGRADE_POSTFIX);
-        super.init();
-    }
-
+    
     /**
-     * Init.
+     * Sets application id.
      *
-     * @param healthCheckDelay  the health check delay
-     * @param healthCheckPeriod the health check period
-     */
-    public void init(long healthCheckDelay, long healthCheckPeriod) {
-        initVars();
-        ExecutorService mergeSendExecutorService = new ThreadPoolExecutor(MAX_MERGE_SEND_THREAD, MAX_MERGE_SEND_THREAD,
-            KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
-            new NamedThreadFactory(getThreadPrefix(MERGE_THREAD_PREFIX), MAX_MERGE_SEND_THREAD));
-        mergeSendExecutorService.submit(new MergedSendRunnable());
-        timerExecutor.scheduleAtFixedRate(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    reconnect(transactionServiceGroup);
-                } catch (Exception ignore) {
-                    LOGGER.error(ignore.getMessage());
-                }
-            }
-        }, healthCheckDelay, healthCheckPeriod, TimeUnit.SECONDS);
-    }
-
-    @Override
-    public Object sendMsgWithResponse(Object msg, long timeout) throws TimeoutException {
-        String validAddress = loadBalance(transactionServiceGroup);
-        Channel acquireChannel = connect(validAddress);
-        Object result = super.sendAsyncRequestWithResponse(validAddress, acquireChannel, msg, timeout);
-        if (result instanceof GlobalBeginResponse
-                && ((GlobalBeginResponse) result).getResultCode() == ResultCode.Failed) {
-            LOGGER.error("begin response error,release channel:" + acquireChannel);
-            releaseChannel(acquireChannel, validAddress);
-        }
-        return result;
-    }
-
-    @Override
-    public Object sendMsgWithResponse(Object msg) throws TimeoutException {
-        return sendMsgWithResponse(msg, NettyClientConfig.getRpcRequestTimeout());
-    }
-
-    @Override
-    public Object sendMsgWithResponse(String serverAddress, Object msg, long timeout)
-        throws TimeoutException {
-        return sendAsyncRequestWithResponse(serverAddress, connect(serverAddress), msg, timeout);
-    }
-
-    @Override
-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
-        if (evt instanceof IdleStateEvent) {
-            IdleStateEvent idleStateEvent = (IdleStateEvent)evt;
-            if (idleStateEvent.state() == IdleState.READER_IDLE) {
-                if (LOGGER.isInfoEnabled()) {
-                    LOGGER.info("channel" + ctx.channel() + " read idle.");
-                }
-                try {
-                    String serverAddress = NetUtil.toStringAddress(ctx.channel().remoteAddress());
-                    nettyClientKeyPool.invalidateObject(poolKeyMap.get(serverAddress), ctx.channel());
-                } catch (Exception exx) {
-                    LOGGER.error(exx.getMessage());
-                } finally {
-                    releaseChannel(ctx.channel(), getAddressFromContext(ctx));
-                }
-            }
-            if (idleStateEvent == IdleStateEvent.WRITER_IDLE_STATE_EVENT) {
-                try {
-                    if (LOGGER.isDebugEnabled()) {
-                        LOGGER.debug("will send ping msg,channel" + ctx.channel());
-                    }
-                    sendRequest(ctx.channel(), HeartbeatMessage.PING);
-                } catch (Throwable throwable) {
-                    LOGGER.error("", "send request error", throwable);
-                }
-            }
-        }
-
-    }
-
-    @Override
-    protected void releaseChannel(Channel channel, String serverAddress) {
-        if (null == channel || null == serverAddress) {
-            return;
-        }
-        try {
-            Object connectLock = channelLocks.get(serverAddress);
-            synchronized (connectLock) {
-                Channel ch = channels.get(serverAddress);
-                if (null == ch) {
-                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-                    return;
-                }
-                if (ch.compareTo(channel) == 0) {
-                    if (LOGGER.isInfoEnabled()) {
-                        LOGGER.info("return to pool, tm channel:" + channel);
-                    }
-                    destroyChannel(serverAddress, channel);
-                } else {
-                    nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-                }
-            }
-        } catch (Exception exx) {
-            LOGGER.error(exx.getMessage());
-        }
-    }
-
-    @Override
-    protected Channel connect(String serverAddress) {
-        Channel channelToServer = channels.get(serverAddress);
-        if (null != channelToServer) {
-            channelToServer = getExistAliveChannel(channelToServer, serverAddress);
-            if (null != channelToServer) {
-                return channelToServer;
-            }
-        }
-        channelLocks.putIfAbsent(serverAddress, new Object());
-        Object connectLock = channelLocks.get(serverAddress);
-        synchronized (connectLock) {
-            channelToServer = doConnect(serverAddress);
-            channels.put(serverAddress, channelToServer);
-            return channelToServer;
-        }
-    }
-
-    private Channel getExistAliveChannel(Channel channel, String serverAddress) {
-        if (channel.isActive()) {
-            return channel;
-        } else {
-            int i = 0;
-            for (; i < NettyClientConfig.getMaxCheckAliveRetry(); i++) {
-                try {
-                    Thread.sleep(NettyClientConfig.getCheckAliveInternal());
-                } catch (InterruptedException exx) {
-                    LOGGER.error(exx.getMessage());
-                }
-                channel = channels.get(serverAddress);
-                if (null == channel || channel.isActive()) {
-                    return channel;
-                }
-            }
-            if (i == NettyClientConfig.getMaxCheckAliveRetry()) {
-                LOGGER.warn("channel " + channel + " is not active after long wait, close it.");
-                releaseChannel(channel, serverAddress);
-                return null;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    protected Config getNettyPoolConfig() {
-        Config poolConfig = new Config();
-        poolConfig.maxActive = tmClientConfig.getMaxPoolActive();
-        poolConfig.minIdle = tmClientConfig.getMinPoolIdle();
-        poolConfig.maxWait = tmClientConfig.getMaxAcquireConnMills();
-        poolConfig.testOnBorrow = tmClientConfig.isPoolTestBorrow();
-        poolConfig.testOnReturn = tmClientConfig.isPoolTestReturn();
-        poolConfig.lifo = tmClientConfig.isPoolLifo();
-        return poolConfig;
-    }
-
-    @Override
-    protected NettyPoolKey.TransactionRole getTransactionRole() {
-        return NettyPoolKey.TransactionRole.TMROLE;
-    }
-
-    /**
-     * Connect channel.
-     *
-     * @param serverAddress the server address
-     * @return the channel
-     */
-    private Channel doConnect(String serverAddress) {
-        Channel channelToServer = channels.get(serverAddress);
-        if (null != channelToServer && channelToServer.isActive()) {
-            return channelToServer;
-        }
-        try {
-            RegisterTMRequest
-                registerTransactionManagerRequest = new RegisterTMRequest(
-                applicationId, transactionServiceGroup);
-            poolKeyMap.putIfAbsent(serverAddress,
-                new NettyPoolKey(getTransactionRole(), serverAddress, registerTransactionManagerRequest));
-            channelToServer = nettyClientKeyPool.borrowObject(poolKeyMap.get(serverAddress));
-        } catch (Exception exx) {
-            LOGGER.error("get channel from pool error.", exx);
-            throw new FrameworkException("can not register TM,err:" + exx.getMessage());
-        }
-        return channelToServer;
-    }
-
-    /**
-     * Gets client app name.
-     *
-     * @return the client app name
-     */
-    public String getApplicationId() {
-        return applicationId;
-    }
-
-    /**
-     * Sets client app name.
-     *
-     * @param applicationId the client app name
+     * @param applicationId the application id
      */
     public void setApplicationId(String applicationId) {
         this.applicationId = applicationId;
     }
-
-    /**
-     * Gets transaction service group.
-     *
-     * @return the transaction service group
-     */
-    public String getTransactionServiceGroup() {
-        return transactionServiceGroup;
-    }
-
+    
     /**
      * Sets transaction service group.
      *
@@ -360,30 +120,39 @@ public final class TmRpcClient extends AbstractRpcRemotingClient {
     public void setTransactionServiceGroup(String transactionServiceGroup) {
         this.transactionServiceGroup = transactionServiceGroup;
     }
-
+    
     @Override
-    public void sendResponse(long msgId, String serverAddress, Object msg) {
-        super.sendResponse(msgId, connect(serverAddress), msg);
+    public void init() {
+        if (initialized.compareAndSet(false, true)) {
+            enableDegrade = CONFIG.getBoolean(ConfigurationKeys.SERVICE_PREFIX + ConfigurationKeys.ENABLE_DEGRADE_POSTFIX);
+            super.init();
+        }
     }
-
+    
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
-        LOGGER.error(FrameworkErrorCode.ExceptionCaught.getErrCode(),
-            NetUtil.toStringAddress(ctx.channel().remoteAddress()) + "connect exception. " + cause.getMessage(), cause);
-        releaseChannel(ctx.channel(), getAddressFromChannel(ctx.channel()));
-        if (LOGGER.isInfoEnabled()) {
-            LOGGER.info("remove exception rm channel:" + ctx.channel());
-        }
-        super.exceptionCaught(ctx, cause);
+    public void destroy() {
+        super.destroy();
+        initialized.getAndSet(false);
+        instance = null;
     }
-
+    
+    @Override
+    protected Function<String, NettyPoolKey> getPoolKeyFunction() {
+        return (severAddress) -> {
+            RegisterTMRequest message = new RegisterTMRequest(applicationId, transactionServiceGroup);
+            return new NettyPoolKey(NettyPoolKey.TransactionRole.TMROLE, severAddress, message);
+        };
+    }
+    
+    @Override
+    public String getTransactionServiceGroup() {
+        return transactionServiceGroup;
+    }
+    
     @Override
     public void onRegisterMsgSuccess(String serverAddress, Channel channel, Object response,
                                      AbstractMessage requestMessage) {
-        if (null != channels.get(serverAddress) && channels.get(serverAddress).isActive()) {
-            return;
-        }
-        channels.put(serverAddress, channel);
+        getClientChannelManager().registerChannel(serverAddress, channel);
     }
 
     @Override
@@ -395,18 +164,4 @@ public final class TmRpcClient extends AbstractRpcRemotingClient {
         }
         throw new FrameworkException("register client app failed.");
     }
-
-    @Override
-    public void destroyChannel(String serverAddress, Channel channel) {
-        if (null == channel) { return; }
-        try {
-            if (channel.equals(channels.get(serverAddress))) {
-                channels.remove(serverAddress);
-            }
-            nettyClientKeyPool.returnObject(poolKeyMap.get(serverAddress), channel);
-        } catch (Exception exx) {
-            LOGGER.error("return channel to rpcPool error:" + exx.getMessage());
-        }
-    }
-
 }
diff --git a/core/src/main/java/io/seata/core/rpc/netty/v1/HeadMapSerializer.java b/core/src/main/java/io/seata/core/rpc/netty/v1/HeadMapSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc625c46060e8193f72d4a7d47cf4a72d6860ef3
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/netty/v1/HeadMapSerializer.java
@@ -0,0 +1,123 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.buffer.ByteBuf;
+import io.seata.common.Constants;
+import io.seata.common.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Common serializer of map (this generally refers to header).
+ *
+ * @author Geng Zhang
+ * @since 0.7.0
+ */
+public class HeadMapSerializer {
+
+    private static final HeadMapSerializer INSTANCE = new HeadMapSerializer();
+
+    private HeadMapSerializer() {
+
+    }
+
+    public static HeadMapSerializer getInstance() {
+        return INSTANCE;
+    }
+
+    /**
+     * encode head map
+     *
+     * @param map header map
+     * @param out ByteBuf
+     * @return length of head map bytes
+     */
+    public int encode(Map<String, String> map, ByteBuf out) {
+        if (map == null || map.isEmpty() || out == null) {
+            return 0;
+        }
+        int start = out.writerIndex();
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            String key = entry.getKey();
+            String value = entry.getValue();
+            if (key != null) {
+                writeString(out, key);
+                writeString(out, value);
+            }
+        }
+        return out.writerIndex() - start;
+    }
+
+    /**
+     * decode head map
+     *
+     * @param in ByteBuf
+     * @param length of head map bytes
+     * @return header map
+     */
+    public Map<String, String> decode(ByteBuf in, int length) {
+        Map<String, String> map = new HashMap<String, String>();
+        if (in == null || in.readableBytes() == 0 || length == 0) {
+            return map;
+        }
+        int tick = in.readerIndex();
+        while (in.readerIndex() - tick < length) {
+            String key = readString(in);
+            String value = readString(in);
+            map.put(key, value);
+        }
+
+        return map;
+    }
+
+    /**
+     * Write string
+     *
+     * @param out ByteBuf
+     * @param str String
+     */
+    protected void writeString(ByteBuf out, String str) {
+        if (str == null) {
+            out.writeShort(-1);
+        } else if (str.isEmpty()) {
+            out.writeShort(0);
+        } else {
+            byte[] bs = str.getBytes(Constants.DEFAULT_CHARSET);
+            out.writeShort(bs.length);
+            out.writeBytes(bs);
+        }
+    }
+    /**
+     * Read string
+     *
+     * @param in ByteBuf
+     * @return String
+     */
+    protected String readString(ByteBuf in) {
+        int length = in.readShort();
+        if (length < 0) {
+            return null;
+        } else if (length == 0) {
+            return StringUtils.EMPTY;
+        } else {
+            byte[] value = new byte[length];
+            in.readBytes(value);
+            return new String(value, Constants.DEFAULT_CHARSET);
+        }
+    }
+}
diff --git a/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Decoder.java b/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Decoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..902760174a55f5cfbd0f65c05df466dd9b5cf1da
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Decoder.java
@@ -0,0 +1,131 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.seata.core.codec.Codec;
+import io.seata.core.codec.CodecFactory;
+import io.seata.core.protocol.HeartbeatMessage;
+import io.seata.core.protocol.ProtocolConstants;
+import io.seata.core.protocol.RpcMessage;
+
+import java.util.Map;
+
+/**
+ * <pre>
+ * 0     1     2     3     4     5     6     7     8     9    10     11    12    13    14    15    16
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * |   magic   |Proto|     Full length       |    Head   | Msg |Seria|Compr|     RequestId         |
+ * |   code    |colVer|    (head+body)      |   Length  |Type |lizer|ess  |                       |
+ * +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
+ * |                                                                                               |
+ * |                                   Head Map [Optional]                                         |
+ * +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
+ * |                                                                                               |
+ * |                                         body                                                  |
+ * |                                                                                               |
+ * |                                        ... ...                                                |
+ * +-----------------------------------------------------------------------------------------------+
+ * </pre>
+ * <p>
+ * <li>Full Length: include all data </li>
+ * <li>Head Length: include head data from magic code to head map. </li>
+ * <li>Body Length: Full Length - Head Length</li>
+ * </p>
+ * https://github.com/seata/seata/issues/893
+ *
+ * @author Geng Zhang
+ * @see ProtocolV1Encoder
+ * @since 0.7.0
+ */
+public class ProtocolV1Decoder extends LengthFieldBasedFrameDecoder {
+
+    public ProtocolV1Decoder() {
+        // default is 8M
+        this(ProtocolConstants.MAX_FRAME_LENGTH);
+    }
+
+    public ProtocolV1Decoder(int maxFrameLength) {
+        /*
+        int maxFrameLength,      
+        int lengthFieldOffset,  magic code is 2B, and version is 1B, and then FullLength. so value is 3
+        int lengthFieldLength,  FullLength is int(4B). so values is 4
+        int lengthAdjustment,   FullLength include all data and read 7 bytes before, so the left length is (FullLength-7). so values is -7
+        int initialBytesToStrip we will check magic code and version self, so do not strip any bytes. so values is 0
+        */
+        super(maxFrameLength, 3, 4, -7, 0);
+    }
+
+    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
+        Object decoded = super.decode(ctx, in);
+        if (decoded instanceof ByteBuf) {
+            ByteBuf frame = (ByteBuf) decoded;
+            return decodeFrame(frame);
+        }
+        return decoded;
+    }
+
+    public Object decodeFrame(ByteBuf frame) {
+        byte b0 = frame.readByte();
+        byte b1 = frame.readByte();
+        if (ProtocolConstants.MAGIC_CODE_BYTES[0] != b0
+                || ProtocolConstants.MAGIC_CODE_BYTES[1] != b1) {
+            throw new IllegalArgumentException("Unknown magic code: " + b0 + ", " + b1);
+        }
+
+        byte version = frame.readByte();
+        // TODO  check version compatible here
+
+        int fullLength = frame.readInt();
+        short headLength = frame.readShort();
+        byte messageType = frame.readByte();
+        byte codecType = frame.readByte();
+        byte compressor = frame.readByte();
+        int requestId = frame.readInt();
+
+        RpcMessage rpcMessage = new RpcMessage();
+        rpcMessage.setCodec(codecType);
+        rpcMessage.setId(requestId);
+        rpcMessage.setCompressor(compressor);
+        rpcMessage.setMessageType(messageType);
+
+        // direct read head with zero-copy
+        int headMapLength = headLength - ProtocolConstants.V1_HEAD_LENGTH;
+        if (headMapLength > 0) {
+            Map<String, String> map = HeadMapSerializer.getInstance().decode(frame, headMapLength);
+            rpcMessage.getHeadMap().putAll(map);
+        }
+
+        // read body
+        if (messageType == ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST) {
+            rpcMessage.setBody(HeartbeatMessage.PING);
+        } else if (messageType == ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE) {
+            rpcMessage.setBody(HeartbeatMessage.PONG);
+        } else {
+            int bodyLength = fullLength - headLength;
+            if (bodyLength > 0) {
+                byte[] bs = new byte[bodyLength];
+                frame.readBytes(bs);
+                Codec codec = CodecFactory.getCodec(codecType);
+                rpcMessage.setBody(codec.decode(bs));
+            }
+        }
+
+        return rpcMessage;
+    }
+}
diff --git a/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Encoder.java b/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Encoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..9315f24b05f40840d0ba9e144eeba149446ca56d
--- /dev/null
+++ b/core/src/main/java/io/seata/core/rpc/netty/v1/ProtocolV1Encoder.java
@@ -0,0 +1,115 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
+import io.seata.core.codec.Codec;
+import io.seata.core.codec.CodecFactory;
+import io.seata.core.protocol.ProtocolConstants;
+import io.seata.core.protocol.RpcMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+
+/**
+ * <pre>
+ * 0     1     2     3     4     5     6     7     8     9    10     11    12    13    14    15    16
+ * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
+ * |   magic   |Proto|     Full length       |    Head   | Msg |Seria|Compr|     RequestId         |
+ * |   code    |colVer|    (head+body)      |   Length  |Type |lizer|ess  |                       |
+ * +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
+ * |                                                                                               |
+ * |                                   Head Map [Optional]                                         |
+ * +-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
+ * |                                                                                               |
+ * |                                         body                                                  |
+ * |                                                                                               |
+ * |                                        ... ...                                                |
+ * +-----------------------------------------------------------------------------------------------+
+ * </pre>
+ * <p>
+ * <li>Full Length: include all data </li>
+ * <li>Head Length: include head data from magic code to head map. </li>
+ * <li>Body Length: Full Length - Head Length</li>
+ * </p>
+ * https://github.com/seata/seata/issues/893
+ *
+ * @author Geng Zhang
+ * @see ProtocolV1Decoder
+ * @since 0.7.0
+ */
+public class ProtocolV1Encoder extends MessageToByteEncoder {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolV1Encoder.class);
+
+    @Override
+    public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) {
+        try {
+            if (msg instanceof RpcMessage) {
+                RpcMessage rpcMessage = (RpcMessage) msg;
+
+                int fullLength = ProtocolConstants.V1_HEAD_LENGTH;
+                int headLength = ProtocolConstants.V1_HEAD_LENGTH;
+
+                byte messageType = rpcMessage.getMessageType();
+                out.writeBytes(ProtocolConstants.MAGIC_CODE_BYTES);
+                out.writeByte(ProtocolConstants.VERSION);
+                // full Length(4B) and head length(2B) will fix in the end. 
+                out.writerIndex(out.writerIndex() + 6);
+                out.writeByte(messageType);
+                out.writeByte(rpcMessage.getCodec());
+                out.writeByte(rpcMessage.getCompressor());
+                out.writeInt(rpcMessage.getId());
+
+                // direct write head with zero-copy
+                Map<String, String> headMap = rpcMessage.getHeadMap();
+                if (headMap != null && !headMap.isEmpty()) {
+                    int headMapBytesLength = HeadMapSerializer.getInstance().encode(headMap, out);
+                    headLength += headMapBytesLength;
+                    fullLength += headMapBytesLength;
+                }
+
+                byte[] bodyBytes = null;
+                if (messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST
+                        && messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE) {
+                    // heartbeat has no body
+                    Codec codec = CodecFactory.getCodec(rpcMessage.getCodec());
+                    bodyBytes = codec.encode(rpcMessage.getBody());
+                    fullLength += bodyBytes.length;
+                }
+
+                if (bodyBytes != null) {
+                    out.writeBytes(bodyBytes);
+                }
+
+                // fix fullLength and headLength
+                int writeIndex = out.writerIndex();
+                // skip magic code(2B) + version(1B)
+                out.writerIndex(writeIndex - fullLength + 3);
+                out.writeInt(fullLength);
+                out.writeShort(headLength);
+                out.writerIndex(writeIndex);
+            } else {
+                throw new UnsupportedOperationException("Not support this class:" + msg.getClass());
+            }
+        } catch (Throwable e) {
+            LOGGER.error("Encode request error!", e);
+        }
+    }
+}
diff --git a/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java b/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
index 9ab9a2a7c5d0f819205e160a5f5e37d12b2b5f73..fdfa220f1735551ed462e6d4d49f4ea609e0d15f 100644
--- a/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
+++ b/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
@@ -15,15 +15,6 @@
  */
 package io.seata.core.store.db;
 
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.sql.DataSource;
-
 import io.seata.common.exception.StoreException;
 import io.seata.common.executor.Initialize;
 import io.seata.common.loader.LoadLevel;
@@ -34,6 +25,14 @@ import io.seata.core.constants.ConfigurationKeys;
 import io.seata.core.store.LockDO;
 import io.seata.core.store.LockStore;
 
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * The type Data base lock store.
  *
@@ -86,9 +85,7 @@ public class LockStoreDataBaseDAO implements LockStore, Initialize {
 
     @Override
     public boolean acquireLock(LockDO lockDO) {
-        List<LockDO> locks = new ArrayList<>();
-        locks.add(lockDO);
-        return acquireLock(locks);
+        return acquireLock(Collections.singletonList(lockDO));
     }
 
     @Override
@@ -169,9 +166,7 @@ public class LockStoreDataBaseDAO implements LockStore, Initialize {
 
     @Override
     public boolean unLock(LockDO lockDO) {
-        List<LockDO> locks = new ArrayList<>();
-        locks.add(lockDO);
-        return unLock(locks);
+        return unLock(Collections.singletonList(lockDO));
     }
 
     @Override
@@ -246,7 +241,6 @@ public class LockStoreDataBaseDAO implements LockStore, Initialize {
      */
     protected boolean doAcquireLock(Connection conn, LockDO lockDO) {
         PreparedStatement ps = null;
-        ResultSet rs = null;
         try {
             //insert
             String insertLockSQL = LockStoreSqls.getInsertLockSQL(lockTable, dbType);
@@ -262,12 +256,6 @@ public class LockStoreDataBaseDAO implements LockStore, Initialize {
         } catch (SQLException e) {
             throw new StoreException(e);
         } finally {
-            if (rs != null) {
-                try {
-                    rs.close();
-                } catch (SQLException e) {
-                }
-            }
             if (ps != null) {
                 try {
                     ps.close();
diff --git a/core/src/test/java/io/seata/core/event/GuavaEventBusTest.java b/core/src/test/java/io/seata/core/event/GuavaEventBusTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a9b306d5aa327654f32700656e8971ab2ca73183
--- /dev/null
+++ b/core/src/test/java/io/seata/core/event/GuavaEventBusTest.java
@@ -0,0 +1,68 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.event;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.google.common.eventbus.Subscribe;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test default GuavaEventBus.
+ *
+ * @author zhengyangyong
+ */
+public class GuavaEventBusTest {
+    @Test
+    public void test() {
+
+        AtomicInteger counter = new AtomicInteger(0);
+        EventBus eventBus = new GuavaEventBus("test");
+
+        class TestEvent implements Event {
+            private final int value;
+
+            public int getValue() {
+                return value;
+            }
+
+            public TestEvent(int value) {
+                this.value = value;
+            }
+        }
+
+        class TestSubscriber {
+            @Subscribe
+            public void process(TestEvent event) {
+                counter.addAndGet(event.getValue());
+            }
+        }
+
+        TestSubscriber subscriber = new TestSubscriber();
+        eventBus.register(subscriber);
+
+        eventBus.post(new TestEvent(1));
+
+        Assertions.assertEquals(1, counter.get());
+
+        eventBus.unregister(subscriber);
+
+        eventBus.post(new TestEvent(1));
+
+        Assertions.assertEquals(1, counter.get());
+    }
+}
diff --git a/core/src/test/java/io/seata/core/message/BranchCommitRequestTest.java b/core/src/test/java/io/seata/core/message/BranchCommitRequestTest.java
index 4431e78c8bb4d696fc3b5ee66021254819f0271a..f30d68bc0751e9098e0fbe425fd75ce7f973aa17 100644
--- a/core/src/test/java/io/seata/core/message/BranchCommitRequestTest.java
+++ b/core/src/test/java/io/seata/core/message/BranchCommitRequestTest.java
@@ -18,8 +18,6 @@ package io.seata.core.message;
 import io.seata.core.model.BranchType;
 import io.seata.core.protocol.transaction.BranchCommitRequest;
 
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.UnpooledByteBufAllocator;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -50,28 +48,4 @@ public class BranchCommitRequestTest {
             + "resourceId=resource1,applicationData=app1", branchCommitRequest.toString());
 
     }
-
-    @Test
-    public void testDecode(){
-        BranchCommitRequest branchCommitRequest = new BranchCommitRequest();
-
-        branchCommitRequest.setXid("127.0.0.1:9999:39875642");
-        branchCommitRequest.setBranchId(1);
-        branchCommitRequest.setBranchType(BranchType.TCC);
-        branchCommitRequest.setResourceId("resource1");
-        branchCommitRequest.setApplicationData("app1");
-
-        byte[] encodeResult = branchCommitRequest.encode();
-
-        ByteBuf byteBuffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(encodeResult.length);
-        byteBuffer.writeBytes(encodeResult);
-
-        BranchCommitRequest decodeBranchCommitRequest = new BranchCommitRequest();
-        decodeBranchCommitRequest.decode(byteBuffer);
-        Assertions.assertEquals(decodeBranchCommitRequest.getXid(), branchCommitRequest.getXid());
-        Assertions.assertEquals(decodeBranchCommitRequest.getBranchId(), branchCommitRequest.getBranchId());
-        Assertions.assertEquals(decodeBranchCommitRequest.getResourceId(), branchCommitRequest.getResourceId());
-        Assertions.assertEquals(decodeBranchCommitRequest.getApplicationData(), branchCommitRequest.getApplicationData());
-        Assertions.assertEquals(decodeBranchCommitRequest.getBranchType(), branchCommitRequest.getBranchType());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/message/BranchCommitResponseTest.java b/core/src/test/java/io/seata/core/message/BranchCommitResponseTest.java
index 03ad73179936ef3006c123da4ddf95f417081c41..7ec8b97888457a56857f222ddd22503f2869dcb0 100644
--- a/core/src/test/java/io/seata/core/message/BranchCommitResponseTest.java
+++ b/core/src/test/java/io/seata/core/message/BranchCommitResponseTest.java
@@ -48,28 +48,4 @@ public class BranchCommitResponseTest {
 
     }
 
-    @Test
-    public void testEncodeDecode() {
-        BranchCommitResponse branchCommitResponse = new BranchCommitResponse();
-
-        branchCommitResponse.setXid("127.0.0.1:9999:39875642");
-        branchCommitResponse.setBranchId(10241024L);
-        branchCommitResponse.setResultCode(ResultCode.Success);
-        branchCommitResponse.setBranchStatus(BranchStatus.PhaseTwo_Committed);
-
-        byte[] encodeResult = branchCommitResponse.encode();
-
-        ByteBuf byteBuffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(encodeResult.length);
-        byteBuffer.writeBytes(encodeResult);
-
-        BranchCommitResponse decodeBranchCommitResponse = new BranchCommitResponse();
-        decodeBranchCommitResponse.decode(byteBuffer);
-        Assertions.assertEquals(decodeBranchCommitResponse.getXid(), branchCommitResponse.getXid());
-        Assertions.assertEquals(decodeBranchCommitResponse.getBranchId(), branchCommitResponse.getBranchId());
-        Assertions.assertEquals(decodeBranchCommitResponse.getResultCode(), branchCommitResponse.getResultCode());
-        Assertions.assertEquals(decodeBranchCommitResponse.getBranchStatus(), branchCommitResponse.getBranchStatus());
-        Assertions.assertEquals(decodeBranchCommitResponse.getTransactionExceptionCode(),
-            branchCommitResponse.getTransactionExceptionCode());
-        Assertions.assertEquals(decodeBranchCommitResponse.getMsg(), branchCommitResponse.getMsg());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/message/BranchRegisterRequestTest.java b/core/src/test/java/io/seata/core/message/BranchRegisterRequestTest.java
index c26a97401afd4d554c077355722a17d37bcbdc24..0cfce45141c666acccfcd3027140133fc1be3ea2 100644
--- a/core/src/test/java/io/seata/core/message/BranchRegisterRequestTest.java
+++ b/core/src/test/java/io/seata/core/message/BranchRegisterRequestTest.java
@@ -42,27 +42,4 @@ public class BranchRegisterRequestTest {
 
     }
 
-    /**
-     * Test decode.
-     */
-    @Test
-    public void testDecode() {
-        BranchRegisterRequest branchRegisterRequest = new BranchRegisterRequest();
-        branchRegisterRequest.setXid("127.0.0.1:8091:1249853");
-        branchRegisterRequest.setBranchType(BranchType.AT);
-        branchRegisterRequest.setResourceId("resource1");
-        branchRegisterRequest.setLockKey("lock_key_1");
-        branchRegisterRequest.setApplicationData("test app data");
-        byte[] encodeResult = branchRegisterRequest.encode();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-        BranchRegisterRequest decodeBranchRegisterRequest = new BranchRegisterRequest();
-        decodeBranchRegisterRequest.decode(byteBuffer);
-        Assertions.assertEquals(branchRegisterRequest.getXid(), decodeBranchRegisterRequest.getXid());
-        Assertions.assertEquals(branchRegisterRequest.getLockKey(), decodeBranchRegisterRequest.getLockKey());
-        Assertions.assertEquals(branchRegisterRequest.getResourceId(), decodeBranchRegisterRequest.getResourceId());
-        Assertions.assertEquals(branchRegisterRequest.getApplicationData(),
-            decodeBranchRegisterRequest.getApplicationData());
-    }
 }
diff --git a/core/src/test/java/io/seata/core/message/BranchReportRequestTest.java b/core/src/test/java/io/seata/core/message/BranchReportRequestTest.java
index 4a9d177836ddf10ba841314f41c2869bd7e8672d..75ac31ac3655f4651751ef18cc37258203e36295 100644
--- a/core/src/test/java/io/seata/core/message/BranchReportRequestTest.java
+++ b/core/src/test/java/io/seata/core/message/BranchReportRequestTest.java
@@ -47,33 +47,4 @@ public class BranchReportRequestTest {
             branchReportRequest.toString());
     }
 
-    /**
-     * Test decode.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testDecode() {
-        BranchReportRequest branchReportRequest = new BranchReportRequest();
-        branchReportRequest.setXid("127.0.0.1:8091:1249853");
-        branchReportRequest.setBranchId(3);
-        branchReportRequest.setResourceId("resource003");
-        branchReportRequest.setStatus(BranchStatus.PhaseOne_Timeout);
-        branchReportRequest.setApplicationData("test app data");
-        branchReportRequest.setBranchType(BranchType.AT);
-
-        byte[] encodeResult = branchReportRequest.encode();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-
-        BranchReportRequest decodeBranchReportRequest = new BranchReportRequest();
-        decodeBranchReportRequest.decode(byteBuffer);
-        Assertions.assertEquals(branchReportRequest.getXid(), decodeBranchReportRequest.getXid());
-        Assertions.assertEquals(branchReportRequest.getBranchId(), decodeBranchReportRequest.getBranchId());
-        Assertions.assertEquals(branchReportRequest.getResourceId(), decodeBranchReportRequest.getResourceId());
-        Assertions.assertEquals(branchReportRequest.getStatus(), decodeBranchReportRequest.getStatus());
-        Assertions.assertEquals(branchReportRequest.getApplicationData(), decodeBranchReportRequest.getApplicationData());
-        Assertions.assertEquals(branchReportRequest.getBranchType(), decodeBranchReportRequest.getBranchType());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/message/CodecTest.java b/core/src/test/java/io/seata/core/message/CodecTest.java
deleted file mode 100644
index d963a78b45b1c214532fea2adfd87bad7e2a444b..0000000000000000000000000000000000000000
--- a/core/src/test/java/io/seata/core/message/CodecTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Copyright 1999-2019 Seata.io Group.
- *
- *  Licensed 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 io.seata.core.message;
-
-import java.nio.ByteBuffer;
-
-import io.seata.core.protocol.ResultCode;
-import io.seata.core.protocol.transaction.BranchRegisterResponse;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-/**
- * The type Codec test.
- *
- * @author jimin.jm @alibaba-inc.com
- */
-public class CodecTest {
-
-    /**
-     * Test a.
-     */
-    @Test
-    public void testA() {
-        long bid = 43554545L;
-        BranchRegisterResponse response = new BranchRegisterResponse();
-        response.setResultCode(ResultCode.Failed);
-        response.setBranchId(bid);
-        byte[] bytes = response.encode();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
-        byteBuffer.put(bytes);
-        byteBuffer.flip();
-
-        BranchRegisterResponse rs = new BranchRegisterResponse();
-        rs.decode(byteBuffer);
-
-        Assertions.assertEquals(response.getBranchId(), rs.getBranchId());
-        Assertions.assertEquals(response.getResultCode(), rs.getResultCode());
-    }
-}
diff --git a/core/src/test/java/io/seata/core/message/GlobalBeginRequestTest.java b/core/src/test/java/io/seata/core/message/GlobalBeginRequestTest.java
index bcfc6fdd0fa6d2251f49f2271d1f07f1e1369ba5..b9c40f137b8eb82f5546536ed582c6488f1d08ab 100644
--- a/core/src/test/java/io/seata/core/message/GlobalBeginRequestTest.java
+++ b/core/src/test/java/io/seata/core/message/GlobalBeginRequestTest.java
@@ -45,42 +45,4 @@ public class GlobalBeginRequestTest {
         Assertions.assertEquals("timeout=60000,transactionName=tran 1", globalBeginRequest.toString());
     }
 
-    /**
-     * Test encode.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testEncode() throws Exception {
-        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
-        globalBeginRequest.setTransactionName("tran 1");
-
-        byte[] encodeResult = globalBeginRequest.encode();
-        String encodeResultStr = Arrays.toString(encodeResult);
-
-        Assertions.assertEquals("[0, 0, -22, 96, 0, 6, 116, 114, 97, 110, 32, 49]", encodeResultStr);
-    }
-
-    /**
-     * Test decode.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testDecode() throws Exception {
-        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
-        globalBeginRequest.setTransactionName("tran 1");
-
-        byte[] encodeResult = globalBeginRequest.encode();
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-
-        GlobalBeginRequest decodeGlobalBeginRequest = new GlobalBeginRequest();
-        decodeGlobalBeginRequest.decode(byteBuffer);
-        System.out.println(decodeGlobalBeginRequest);
-        Assertions.assertEquals(globalBeginRequest.getTimeout(), decodeGlobalBeginRequest.getTimeout());
-        Assertions.assertEquals(globalBeginRequest.getTransactionName(), decodeGlobalBeginRequest.getTransactionName());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/message/GlobalCommitResponseTest.java b/core/src/test/java/io/seata/core/message/GlobalCommitResponseTest.java
index 6ce6a651df8990a261f230ae8f05aae01dbe69d7..d60f93fba48317d6254acb9cb674cbfdd1f6ce4f 100644
--- a/core/src/test/java/io/seata/core/message/GlobalCommitResponseTest.java
+++ b/core/src/test/java/io/seata/core/message/GlobalCommitResponseTest.java
@@ -52,87 +52,4 @@ public class GlobalCommitResponseTest {
         Assertions.assertEquals("globalStatus=Committed,ResultCode=Success,Msg=OK", globalCommitResponse.toString());
     }
 
-    /**
-     * Test encode.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testEncode() throws Exception {
-        GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
-
-        globalCommitResponse.setGlobalStatus(GlobalStatus.Committed);
-        globalCommitResponse.setResultCode(ResultCode.Success);
-        globalCommitResponse.setMsg("OK");
-
-        System.out.println(globalCommitResponse.toString());
-
-        byte[] encodeResult = globalCommitResponse.encode();
-        System.out.println(encodeResult);
-        String encodeResultStr = Arrays.toString(encodeResult);
-        System.out.println(encodeResultStr);
-
-        Assertions.assertEquals("[1, 0, 9]", encodeResultStr);
-    }
-
-    /**
-     * Test decode normal.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testDecodeNormal() throws Exception {
-        GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
-
-        globalCommitResponse.setGlobalStatus(GlobalStatus.Committed);
-        globalCommitResponse.setResultCode(ResultCode.Success);
-        globalCommitResponse.setMsg("OK");
-
-        System.out.println(globalCommitResponse.toString());
-
-        byte[] encodeResult = globalCommitResponse.encode();
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-        GlobalCommitResponse decodeGlobalCommitResponse = new GlobalCommitResponse();
-        decodeGlobalCommitResponse.decode(byteBuffer);
-
-        System.out.println(decodeGlobalCommitResponse.toString());
-
-        Assertions.assertEquals(globalCommitResponse.getGlobalStatus(), decodeGlobalCommitResponse.getGlobalStatus());
-        Assertions.assertEquals(globalCommitResponse.getResultCode(), decodeGlobalCommitResponse.getResultCode());
-        //success response do not have msg
-        Assertions.assertTrue(StringUtils.isBlank(decodeGlobalCommitResponse.getMsg()));
-    }
-
-    /**
-     * Test decode exception.
-     *
-     * @throws Exception the exception
-     */
-    @Test
-    public void testDecodeException() throws Exception {
-        GlobalCommitResponse globalCommitResponse = new GlobalCommitResponse();
-
-        globalCommitResponse.setGlobalStatus(GlobalStatus.CommitFailed);
-        globalCommitResponse.setResultCode(ResultCode.Failed);
-        globalCommitResponse.setMsg("error happened");
-
-        System.out.println(globalCommitResponse.toString());
-
-        byte[] encodeResult = globalCommitResponse.encode();
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-        GlobalCommitResponse decodeGlobalCommitResponse = new GlobalCommitResponse();
-        decodeGlobalCommitResponse.decode(byteBuffer);
-
-        System.out.println(decodeGlobalCommitResponse.toString());
-
-        Assertions.assertEquals(globalCommitResponse.getGlobalStatus(), decodeGlobalCommitResponse.getGlobalStatus());
-        Assertions.assertEquals(globalCommitResponse.getResultCode(), decodeGlobalCommitResponse.getResultCode());
-        Assertions.assertEquals(globalCommitResponse.getMsg(), decodeGlobalCommitResponse.getMsg());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/message/GlobalRollbackRequestTest.java b/core/src/test/java/io/seata/core/message/GlobalRollbackRequestTest.java
index 0723153c77837489a69cea5ff3048b5339377f46..547ef35983425f9b43673f0f496fc21838517c14 100644
--- a/core/src/test/java/io/seata/core/message/GlobalRollbackRequestTest.java
+++ b/core/src/test/java/io/seata/core/message/GlobalRollbackRequestTest.java
@@ -38,21 +38,4 @@ public class GlobalRollbackRequestTest {
         Assertions.assertEquals("xid=127.0.0.1:8091:1249853,extraData=test_extra_data", globalRollbackRequest.toString());
     }
 
-    /**
-     * Test decode.
-     */
-    @Test
-    public void testDecode() {
-        GlobalRollbackRequest globalRollbackRequest = new GlobalRollbackRequest();
-        globalRollbackRequest.setXid("127.0.0.1:8091:1249853");
-        globalRollbackRequest.setExtraData("test_extra_data");
-        byte[] encodeResult = globalRollbackRequest.encode();
-        ByteBuffer byteBuffer = ByteBuffer.allocate(encodeResult.length);
-        byteBuffer.put(encodeResult);
-        byteBuffer.flip();
-        GlobalRollbackRequest decodeGlobalRollbackRequest = new GlobalRollbackRequest();
-        decodeGlobalRollbackRequest.decode(byteBuffer);
-        Assertions.assertEquals(globalRollbackRequest.getXid(), decodeGlobalRollbackRequest.getXid());
-        Assertions.assertEquals(globalRollbackRequest.getExtraData(), decodeGlobalRollbackRequest.getExtraData());
-    }
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/protocol/MergeResultMessageTest.java b/core/src/test/java/io/seata/core/protocol/MergeResultMessageTest.java
index 8301b7ca7dc8c04a53cc7aa2302d50fa8544d170..a91d2b11d64259b7e156ce538e6e022377295357 100644
--- a/core/src/test/java/io/seata/core/protocol/MergeResultMessageTest.java
+++ b/core/src/test/java/io/seata/core/protocol/MergeResultMessageTest.java
@@ -42,36 +42,7 @@ public class MergeResultMessageTest {
     @Test
     public void getTypeCode() {
         MergeResultMessage mergeResultMessage = new MergeResultMessage();
-        assertThat(AbstractMessage.TYPE_SEATA_MERGE_RESULT).isEqualTo(mergeResultMessage.getTypeCode());
-    }
-
-    @Test
-    public void encode() {
-        byte[] expect = new byte[]{0, 0, 0, 17, 0, 1, 0, 2, 1, 0, 0, 3, 120, 105, 100, 0, 4, 100, 97, 116, 97};
-        MergeResultMessage mergeResultMessage = new MergeResultMessage();
-        final AbstractResultMessage[] msgs = new AbstractResultMessage[1];
-        final GlobalBeginResponse globalBeginResponse = buildGlobalBeginResponse();
-        msgs[0] = globalBeginResponse;
-        mergeResultMessage.setMsgs(msgs);
-        byte[] result = mergeResultMessage.encode();
-        assertThat(expect).isEqualTo(result);
-    }
-
-    @Test
-    public void decode() {
-
-        byte[] result = new byte[]{0, 0, 0, 17, 0, 1, 0, 2, 1, 0, 0, 3, 120, 105, 100, 0, 4, 100, 97, 116, 97};
-        final GlobalBeginResponse globalBeginResponse = buildGlobalBeginResponse();
-        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
-        MergeResultMessage decodeResult = new MergeResultMessage();
-        decodeResult.decode(buffer.writeBytes(result));
-        GlobalBeginResponse decodeGlobalBeginResponse = (GlobalBeginResponse) decodeResult.getMsgs()[0];
-
-        assertThat(globalBeginResponse.getExtraData()).isEqualTo(decodeGlobalBeginResponse.getExtraData());
-        assertThat(globalBeginResponse.getXid()).isEqualTo(decodeGlobalBeginResponse.getXid());
-        assertThat(globalBeginResponse.getResultCode()).isEqualTo(decodeGlobalBeginResponse.getResultCode());
-        //msg won't be coded
-        assertThat(decodeGlobalBeginResponse.getMsg()).isNull();
+        assertThat(MessageType.TYPE_SEATA_MERGE_RESULT).isEqualTo(mergeResultMessage.getTypeCode());
     }
 
     private GlobalBeginResponse buildGlobalBeginResponse() {
diff --git a/core/src/test/java/io/seata/core/protocol/MergedWarpMessageTest.java b/core/src/test/java/io/seata/core/protocol/MergedWarpMessageTest.java
index ee6b9d03dd04c4b41d85145c8f771394b4e5aa7f..2426ba7837ed5a57a44187bef1113176743d93be 100644
--- a/core/src/test/java/io/seata/core/protocol/MergedWarpMessageTest.java
+++ b/core/src/test/java/io/seata/core/protocol/MergedWarpMessageTest.java
@@ -34,38 +34,7 @@ public class MergedWarpMessageTest {
     @Test
     public void getTypeCode() {
         MergedWarpMessage mergedWarpMessage = new MergedWarpMessage();
-        assertThat(mergedWarpMessage.getTypeCode()).isEqualTo(AbstractMessage.TYPE_SEATA_MERGE);
-    }
-
-    @Test
-    public void encode() {
-        //you can run encode to get the data
-        byte[] expect = new byte[]{0, 0, 0, 12, 0, 1, 0, 1, 0, 0, 11, -72, 0, 2, 120, 120};
-        MergedWarpMessage mergedWarpMessage = new MergedWarpMessage();
-        final ArrayList<AbstractMessage> msgs = new ArrayList<>();
-        final GlobalBeginRequest globalBeginRequest = buildGlobalBeginRequest();
-        msgs.add(globalBeginRequest);
-        mergedWarpMessage.msgs = msgs;
-        byte[] result = mergedWarpMessage.encode();
-        assertThat(expect).isEqualTo(result);
-    }
-
-    @Test
-    public void decode() {
-        final GlobalBeginRequest globalBeginRequest = buildGlobalBeginRequest();
-        byte[] result = new byte[]{0, 0, 0, 12, 0, 1, 0, 1, 0, 0, 11, -72, 0, 2, 120, 120};
-        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
-        MergedWarpMessage decodeResult = new MergedWarpMessage();
-        decodeResult.decode(buffer.writeBytes(result));
-        final AbstractMessage expected = decodeResult.msgs.get(0);
-        assertThat(true).isEqualTo(expected instanceof GlobalBeginRequest);
-        GlobalBeginRequest decodeGlobalBeginRequest = (GlobalBeginRequest) expected;
-
-        assertThat(globalBeginRequest.getTransactionName()).isEqualTo(decodeGlobalBeginRequest.getTransactionName());
-        assertThat(globalBeginRequest.getTimeout()).isEqualTo(decodeGlobalBeginRequest.getTimeout());
-        assertThat(globalBeginRequest.getTimeout()).isEqualTo(decodeGlobalBeginRequest.getTimeout());
-        assertThat(globalBeginRequest.getTypeCode()).isEqualTo(decodeGlobalBeginRequest.getTypeCode());
-        assertThat("xx").isEqualTo(decodeGlobalBeginRequest.getTransactionName());
+        assertThat(mergedWarpMessage.getTypeCode()).isEqualTo(MessageType.TYPE_SEATA_MERGE);
     }
 
     private GlobalBeginRequest buildGlobalBeginRequest() {
diff --git a/core/src/test/java/io/seata/core/protocol/MessageFutureTest.java b/core/src/test/java/io/seata/core/protocol/MessageFutureTest.java
index 1ffafc89311f62a4ebb27a8648481ce703c66739..9944a612bfca1e9830936d56346323206117aab0 100644
--- a/core/src/test/java/io/seata/core/protocol/MessageFutureTest.java
+++ b/core/src/test/java/io/seata/core/protocol/MessageFutureTest.java
@@ -19,6 +19,7 @@ import com.alibaba.fastjson.JSON;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.util.HashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -35,12 +36,13 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 public class MessageFutureTest {
 
-    private final boolean ASYNC_FIELD = false;
-    private final String BODY_FIELD = "test_body";
-    private final boolean HEART_BEAT_FIELD = true;
-    private final boolean REQUEST_FIELD = false;
-    private final long ID_FIELD = 100L;
-    private final long TIME_OUT_FIELD = 100L;
+    private static final String BODY_FIELD = "test_body";
+    private static final int ID_FIELD = 100;
+    private static final byte CODEC_FIELD = 1;
+    private static final byte COMPRESS_FIELD = 2;
+    private static final byte MSG_TYPE_FIELD = 3;
+    private static final HashMap<String, String> HEAD_FIELD = new HashMap<>();
+    private static final long TIME_OUT_FIELD = 100L;
 
     /**
      * Test field set get.
@@ -49,11 +51,12 @@ public class MessageFutureTest {
     public void testFieldSetGet() {
         String fromJson = "{\n" +
                 "\t\"requestMessage\":{\n" +
-                "\t\t\"async\":" + ASYNC_FIELD + ",\n" +
                 "\t\t\"body\":\"" + BODY_FIELD + "\",\n" +
-                "\t\t\"heartbeat\":" + HEART_BEAT_FIELD + ",\n" +
+                "\t\t\"codec\":" + CODEC_FIELD + ",\n" +
+                "\t\t\"compressor\":" + COMPRESS_FIELD + ",\n" +
+                "\t\t\"headMap\":" + HEAD_FIELD + ",\n" +
                 "\t\t\"id\":" + ID_FIELD + ",\n" +
-                "\t\t\"request\":" + REQUEST_FIELD + "\n" +
+                "\t\t\"messageType\":" + MSG_TYPE_FIELD + "\n" +
                 "\t},\n" +
                 "\t\"timeout\":" + TIME_OUT_FIELD + "\n" +
                 "}";
@@ -187,9 +190,9 @@ public class MessageFutureTest {
     private RpcMessage buildRepcMessage() {
         RpcMessage rpcMessage = new RpcMessage();
         rpcMessage.setId(ID_FIELD);
-        rpcMessage.setAsync(ASYNC_FIELD);
-        rpcMessage.setRequest(REQUEST_FIELD);
-        rpcMessage.setHeartbeat(HEART_BEAT_FIELD);
+        rpcMessage.setMessageType(MSG_TYPE_FIELD);
+        rpcMessage.setCodec(CODEC_FIELD);
+        rpcMessage.setCompressor(COMPRESS_FIELD);
         rpcMessage.setBody(BODY_FIELD);
         return rpcMessage;
     }
diff --git a/core/src/test/java/io/seata/core/protocol/RegisterRMRequestTest.java b/core/src/test/java/io/seata/core/protocol/RegisterRMRequestTest.java
index efede6452e9bac0113dcf3d72bfa20c9377762c4..394a44fb14b0c44c2593c0c0dee0a8b3f733bade 100644
--- a/core/src/test/java/io/seata/core/protocol/RegisterRMRequestTest.java
+++ b/core/src/test/java/io/seata/core/protocol/RegisterRMRequestTest.java
@@ -40,35 +40,9 @@ public class RegisterRMRequestTest {
     @Test
     public void getTypeCode() {
         RegisterRMRequest registerRMRequest = new RegisterRMRequest();
-        assertThat(AbstractMessage.TYPE_REG_RM).isEqualTo(registerRMRequest.getTypeCode());
+        assertThat(MessageType.TYPE_REG_RM).isEqualTo(registerRMRequest.getTypeCode());
     }
 
-
-    @Test
-    public void encode() {
-        byte[] expect = new byte[]{0, 1, 49, 0, 3, 97, 112, 112, 0, 5, 103, 114, 111, 117, 112, 0, 5, 101, 120, 116, 114, 97, 0, 0, 0, 5, 114, 49, 44, 114, 50};
-        RegisterRMRequest registerRMRequest = buildRegisterRMRequest();
-        byte[] result = registerRMRequest.encode();
-        assertThat(expect).isEqualTo(result);
-    }
-
-
-    @Test
-    public void decode() {
-        byte[] result = new byte[]{0, 1, 49, 0, 3, 97, 112, 112, 0, 5, 103, 114, 111, 117, 112, 0, 5, 101, 120, 116, 114, 97, 0, 0, 0, 5, 114, 49, 44, 114, 50};
-        RegisterRMRequest registerRMRequest = buildRegisterRMRequest();
-        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
-        RegisterRMRequest decodeResult = new RegisterRMRequest();
-        decodeResult.decode(buffer.writeBytes(result));
-        assertThat(decodeResult.getTypeCode()).isEqualTo(registerRMRequest.getTypeCode());
-        assertThat(decodeResult.getResourceIds()).isEqualTo(registerRMRequest.getResourceIds());
-        assertThat(decodeResult.getApplicationId()).isEqualTo(registerRMRequest.getApplicationId());
-        assertThat(decodeResult.getExtraData()).isEqualTo(registerRMRequest.getExtraData());
-        assertThat(decodeResult.getTransactionServiceGroup()).isEqualTo(registerRMRequest.getTransactionServiceGroup());
-        assertThat(decodeResult.getVersion()).isEqualTo(registerRMRequest.getVersion());
-    }
-
-
     private RegisterRMRequest buildRegisterRMRequest() {
 
         RegisterRMRequest registerRMRequest = new RegisterRMRequest();
diff --git a/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java b/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
index d76a6c79dc47e8822849b119e70de30be98f51fa..8d4b83f9e33b86ee30f501bd5417c84a39f6d329 100644
--- a/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
+++ b/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
@@ -15,6 +15,8 @@
  */
 package io.seata.core.protocol;
 
+import io.seata.core.codec.CodecFactory;
+import io.seata.core.codec.CodecType;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -42,151 +44,6 @@ public class RegisterTMRequestTest {
 	private static final short TYPE_CODE = 101;
 	private static final ByteBuf BB = buffer(128);
 	
-	/** Constructor without arguments **/
-	@BeforeAll
-	public static void setupNull() {
-		registerTMRequest = new RegisterTMRequest();
-		air = Mockito.mock(
-				AbstractIdentifyRequest.class, 
-			    Mockito.CALLS_REAL_METHODS);
-	}
 
-	/** Constructor with arguments **/
-	@BeforeAll
-	public static void setupWithValues() {
-		registerTMRequest = new RegisterTMRequest(APP_ID, TSG, ED);
-		air = Mockito.mock(
-				AbstractIdentifyRequest.class, 
-			    Mockito.CALLS_REAL_METHODS);
-	}
-
-	/** Test get type code **/
-	@Test
-	public void testGetTypeCode() {
-		Assertions.assertEquals(TYPE_CODE, registerTMRequest.getTypeCode());
-	}
-
-	/**
-	 * Test toString having all the parameters initialized to null
-	 */
-	@Test
-	public void testToStringNullValues() {
-		Assertions.assertEquals("RegisterTMRequest{" + "applicationId='" + null + '\'' + ", transactionServiceGroup='"
-				+ null + '\'' + '}', registerTMRequest.toString());
-	}
-
-	/**
-	 * Test decode method with empty parameter
-	 */
-	@Test
-	public void testDecodeEmpty() {
-		BB.clear();
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeLessThanTwo() {
-		BB.clear();
-		for (int i = 0; i < 2; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeMoreThanThree() {
-		BB.clear();
-		for (int i = 0; i < 3; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeLessThanFour() {
-		BB.clear();
-		for (int i = 0; i < 4; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeMoreLessThanOne() {
-		BB.clear();
-		for (int i = 0; i < 1; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeMoreLessThanFourWithZero() {
-		BB.clear();
-		for (int i = 0; i < 4; i++) {
-			BB.writeZero(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeFalseLessThanTwoWithDifferentReadable() {
-		BB.clear();
-		for (int i = 0; i < 1; i++) {
-			BB.writeZero(i);
-		}
-		for (int i = 1; i < 2; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertFalse(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeTrueLessThanFive() {
-		BB.clear();
-		for (int i = 0; i < 4; i++) {
-			BB.writeZero(i);
-		}
-		for (int i = 4; i < 5; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertTrue(air.decode(BB));
-	}
-	
-	/**
-	 * Test decode method with initialized parameter
-	 */
-	@Test
-	public void testDecodeTrueLessThanSixteen() {
-		BB.clear();
-		for (int i = 0; i < 15; i++) {
-			BB.writeZero(i);
-		}
-		for (int i = 15; i < 16; i++) {
-			BB.writeShort(i);
-		}
-		Assertions.assertTrue(air.decode(BB));
-	}
 	
 }
diff --git a/core/src/test/java/io/seata/core/protocol/RpcMessageTest.java b/core/src/test/java/io/seata/core/protocol/RpcMessageTest.java
index 180dbcf7efc7feb021ef29efc31cfe02c11a0f77..833719b046f45b25d5b2ecfe9fa3c2aba9bf4731 100644
--- a/core/src/test/java/io/seata/core/protocol/RpcMessageTest.java
+++ b/core/src/test/java/io/seata/core/protocol/RpcMessageTest.java
@@ -16,9 +16,10 @@
 package io.seata.core.protocol;
 
 import com.alibaba.fastjson.JSON;
-
 import org.junit.jupiter.api.Test;
 
+import java.util.HashMap;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 /**
@@ -29,11 +30,12 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 public class RpcMessageTest {
 
-    private final boolean ASYNC_FIELD = false;
-    private final String BODY_FIELD = "test_body";
-    private final boolean HEART_BEAT_FIELD = true;
-    private final boolean REQUEST_FIELD = false;
-    private final long ID_FIELD = 100L;
+    private static final String BODY_FIELD = "test_body";
+    private static final int ID_FIELD = 100;
+    private static final byte CODEC_FIELD = 1;
+    private static final byte COMPRESS_FIELD = 2;
+    private static final byte MSG_TYPE_FIELD = 3;
+    private static final HashMap<String, String> HEAD_FIELD = new HashMap<>();
 
     /**
      * Test field get set from json.
@@ -41,39 +43,25 @@ public class RpcMessageTest {
     @Test
     public void testFieldGetSetFromJson() {
         String fromJson = "{\n" +
-            "\t\"async\":" + ASYNC_FIELD + ",\n" +
-            "\t\"body\":\"" + BODY_FIELD + "\",\n" +
-            "\t\"heartbeat\":" + HEART_BEAT_FIELD + ",\n" +
-            "\t\"id\":" + ID_FIELD + ",\n" +
-            "\t\"request\":" + REQUEST_FIELD + "\n" +
-            "}";
+                "\t\"body\":\"" + BODY_FIELD + "\",\n" +
+                "\t\"codec\":" + CODEC_FIELD + ",\n" +
+                "\t\"compressor\":" + COMPRESS_FIELD + ",\n" +
+                "\t\"headMap\":" + HEAD_FIELD + ",\n" +
+                "\t\"id\":" + ID_FIELD + ",\n" +
+                "\t\"messageType\":" + MSG_TYPE_FIELD + "\n" +
+                "}";
         RpcMessage fromJsonMessage = JSON.parseObject(fromJson, RpcMessage.class);
-        assertThat(fromJsonMessage.isAsync()).isEqualTo(ASYNC_FIELD);
-        assertThat(fromJsonMessage.isHeartbeat()).isEqualTo(HEART_BEAT_FIELD);
-        assertThat(fromJsonMessage.isRequest()).isEqualTo(REQUEST_FIELD);
         assertThat(fromJsonMessage.getBody()).isEqualTo(BODY_FIELD);
         assertThat(fromJsonMessage.getId()).isEqualTo(ID_FIELD);
 
         RpcMessage toJsonMessage = new RpcMessage();
-        toJsonMessage.setAsync(ASYNC_FIELD);
         toJsonMessage.setBody(BODY_FIELD);
-        toJsonMessage.setRequest(REQUEST_FIELD);
-        toJsonMessage.setHeartbeat(HEART_BEAT_FIELD);
         toJsonMessage.setId(ID_FIELD);
+        toJsonMessage.setMessageType(MSG_TYPE_FIELD);
+        toJsonMessage.setCodec(CODEC_FIELD);
+        toJsonMessage.setCompressor(COMPRESS_FIELD);
+        toJsonMessage.setHeadMap(HEAD_FIELD);
         String toJson = JSON.toJSONString(toJsonMessage, true);
         assertThat(fromJson).isEqualTo(toJson);
     }
-
-    /**
-     * Test get next message id.
-     */
-    @Test
-    public void testGetNextMessageId() {
-        long startMessageId = RpcMessage.getNextMessageId();
-        assertThat(RpcMessage.getNextMessageId()).isEqualTo(1 + startMessageId);
-        assertThat(RpcMessage.getNextMessageId()).isEqualTo(2 + startMessageId);
-        assertThat(RpcMessage.getNextMessageId()).isEqualTo(3 + startMessageId);
-        assertThat(RpcMessage.getNextMessageId()).isEqualTo(4 + startMessageId);
-        assertThat(RpcMessage.getNextMessageId()).isEqualTo(5 + startMessageId);
-    }
 }
diff --git a/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackRequestTest.java b/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackRequestTest.java
index 0f77c30ff450a02c1d5959c90b6ecceef2922e5e..a6397404a99d21a1f7fa918e25f3125ac4319832 100644
--- a/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackRequestTest.java
+++ b/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackRequestTest.java
@@ -42,29 +42,4 @@ public class BranchRollbackRequestTest {
 
     }
 
-    @Test
-    public void testEncodeDecode() {
-        BranchRollbackRequest branchRollbackRequest = new BranchRollbackRequest();
-
-        branchRollbackRequest.setXid("127.0.0.1:9999:39875642");
-        branchRollbackRequest.setBranchId(1);
-        branchRollbackRequest.setBranchType(BranchType.TCC);
-        branchRollbackRequest.setResourceId("resource1");
-        branchRollbackRequest.setApplicationData("app1");
-
-        byte[] encodeResult = branchRollbackRequest.encode();
-
-        ByteBuf byteBuffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(encodeResult.length);
-        byteBuffer.writeBytes(encodeResult);
-
-        BranchRollbackRequest decodeBranchRollbackRequest = new BranchRollbackRequest();
-        decodeBranchRollbackRequest.decode(byteBuffer);
-        Assertions.assertEquals(decodeBranchRollbackRequest.getXid(), branchRollbackRequest.getXid());
-        Assertions.assertEquals(decodeBranchRollbackRequest.getBranchId(), branchRollbackRequest.getBranchId());
-        Assertions.assertEquals(decodeBranchRollbackRequest.getResourceId(), branchRollbackRequest.getResourceId());
-        Assertions.assertEquals(decodeBranchRollbackRequest.getApplicationData(),
-            decodeBranchRollbackRequest.getApplicationData());
-        Assertions.assertEquals(decodeBranchRollbackRequest.getBranchType(), branchRollbackRequest.getBranchType());
-    }
-
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackResponseTest.java b/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackResponseTest.java
index 9b50e0015de1ab7303c697a4e602efb84c76ce9b..341cf76a578fc755902efc75dfbb36171d37f865 100644
--- a/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackResponseTest.java
+++ b/core/src/test/java/io/seata/core/protocol/transaction/BranchRollbackResponseTest.java
@@ -41,29 +41,4 @@ public class BranchRollbackResponseTest {
 
     }
 
-    @Test
-    public void testEncodeDecode() {
-        BranchRollbackResponse branchRollbackResponse = new BranchRollbackResponse();
-
-        branchRollbackResponse.setXid("127.0.0.1:9999:39875642");
-        branchRollbackResponse.setBranchId(10241024L);
-        branchRollbackResponse.setResultCode(ResultCode.Success);
-        branchRollbackResponse.setBranchStatus(BranchStatus.PhaseTwo_Committed);
-
-        byte[] encodeResult = branchRollbackResponse.encode();
-
-        ByteBuf byteBuffer = UnpooledByteBufAllocator.DEFAULT.directBuffer(encodeResult.length);
-        byteBuffer.writeBytes(encodeResult);
-
-        BranchRollbackResponse decodeBranchRollbackResponse = new BranchRollbackResponse();
-        decodeBranchRollbackResponse.decode(byteBuffer);
-        Assertions.assertEquals(decodeBranchRollbackResponse.getXid(), branchRollbackResponse.getXid());
-        Assertions.assertEquals(decodeBranchRollbackResponse.getBranchId(), branchRollbackResponse.getBranchId());
-        Assertions.assertEquals(decodeBranchRollbackResponse.getResultCode(), branchRollbackResponse.getResultCode());
-        Assertions.assertEquals(decodeBranchRollbackResponse.getBranchStatus(), branchRollbackResponse.getBranchStatus());
-        Assertions.assertEquals(decodeBranchRollbackResponse.getTransactionExceptionCode(),
-            branchRollbackResponse.getTransactionExceptionCode());
-        Assertions.assertEquals(decodeBranchRollbackResponse.getMsg(), branchRollbackResponse.getMsg());
-    }
-
-}
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/protocol/transaction/GlobalBeginResponseTest.java b/core/src/test/java/io/seata/core/protocol/transaction/GlobalBeginResponseTest.java
index beb7bcac9c4f5cab306297e56b49b327659ea451..9457e53b8fa629361250d2c5910069fbc76a6df6 100644
--- a/core/src/test/java/io/seata/core/protocol/transaction/GlobalBeginResponseTest.java
+++ b/core/src/test/java/io/seata/core/protocol/transaction/GlobalBeginResponseTest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.core.protocol.transaction;
 
+import io.seata.core.protocol.MessageType;
 import io.seata.core.protocol.ResultCode;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -51,20 +52,7 @@ public class GlobalBeginResponseTest {
     @Test
     public void testGetTypeCode() {
         GlobalBeginResponse globalBeginResponse = new GlobalBeginResponse();
-        Assertions.assertEquals(GlobalBeginResponse.TYPE_GLOBAL_BEGIN_RESULT, globalBeginResponse.getTypeCode());
+        Assertions.assertEquals(MessageType.TYPE_GLOBAL_BEGIN_RESULT, globalBeginResponse.getTypeCode());
     }
 
-    @Test
-    public void testDoEncodeAndDecode() {
-        GlobalBeginResponse globalBeginResponseOne = new GlobalBeginResponse();
-        globalBeginResponseOne.setXid(XID);
-        globalBeginResponseOne.setExtraData(EXTRA_DATA);
-        globalBeginResponseOne.setResultCode(RESULT_CODE);
-        byte[] encode = globalBeginResponseOne.encode();
-        GlobalBeginResponse globalBeginResponseTwo = new GlobalBeginResponse();
-        globalBeginResponseTwo.decode(ByteBuffer.wrap(encode));
-        assertThat(globalBeginResponseOne.getXid()).isEqualTo(globalBeginResponseTwo.getXid());
-        assertThat(globalBeginResponseOne.getExtraData()).isEqualTo(globalBeginResponseTwo.getExtraData());
-        assertThat(globalBeginResponseOne.getResultCode()).isEqualTo(globalBeginResponseTwo.getResultCode());
-    }
 }
diff --git a/core/src/test/java/io/seata/core/rpc/netty/MessageCodecHandlerTest.java b/core/src/test/java/io/seata/core/rpc/netty/MessageCodecHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5feeb6ae9aab4ccd91b5fcd5ba129e5e6377ad6b
--- /dev/null
+++ b/core/src/test/java/io/seata/core/rpc/netty/MessageCodecHandlerTest.java
@@ -0,0 +1,93 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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.
+ */
+///*
+// *  Copyright 1999-2019 Seata.io Group.
+// *
+// *  Licensed 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 io.seata.core.rpc.netty;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//
+//import io.netty.buffer.ByteBuf;
+//import io.netty.buffer.UnpooledByteBufAllocator;
+//import io.netty.channel.ChannelHandlerContext;
+//import io.seata.core.protocol.RpcMessage;
+//import io.seata.core.protocol.transaction.GlobalBeginRequest;
+//import org.junit.Ignore;
+//import org.junit.jupiter.api.Test;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//import static org.assertj.core.api.Assertions.fail;
+//
+//public class MessageCodecHandlerTest {
+//
+//    @Test
+//    @Ignore("seata serialize can not support this way,only we can change serialize type dynamicly.")
+//    public void encodeAndDecode() {
+//
+//        MessageCodecHandler messageCodecHandler = new MessageCodecHandler();
+//        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.directBuffer(1024);
+//
+//        GlobalBeginRequest globalBeginRequest = new GlobalBeginRequest();
+//        globalBeginRequest.setTransactionName("trans-1");
+//        globalBeginRequest.setTimeout(3000);
+//
+//        RpcMessage msg = new RpcMessage();
+//        msg.setId(1);
+//        msg.setAsync(false);
+//        msg.setHeartbeat(false);
+//        msg.setRequest(true);
+//        msg.setBody(globalBeginRequest);
+//        ChannelHandlerContext ctx = null;
+//        try {
+//            messageCodecHandler.encode(ctx, msg, out);
+//        } catch (Exception e) {
+//            fail(e.getMessage());
+//        }
+//        List<Object> objetcs = new ArrayList<>();
+//        try {
+//            messageCodecHandler.decode(ctx, out, objetcs);
+//        } catch (Exception e) {
+//            fail(e.getMessage());
+//        }
+//
+//        assertThat(objetcs.size()).isEqualTo(1);
+//        final Object actual = objetcs.get(0);
+//        assertThat(actual instanceof RpcMessage).isEqualTo(true);
+//
+//        RpcMessage rpcMessage = (RpcMessage)actual;
+//
+//        GlobalBeginRequest decodeGlobalBeginRequest = (GlobalBeginRequest)rpcMessage.getBody();
+//        assertThat(decodeGlobalBeginRequest.getTransactionName()).isEqualTo(
+//            globalBeginRequest.getTransactionName());
+//        assertThat(decodeGlobalBeginRequest.getTimeout()).isEqualTo(globalBeginRequest.getTimeout());
+//        assertThat(decodeGlobalBeginRequest.getTypeCode()).isEqualTo(globalBeginRequest.getTypeCode());
+//
+//    }
+//
+//}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/rpc/netty/NettyClientChannelManagerTest.java b/core/src/test/java/io/seata/core/rpc/netty/NettyClientChannelManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb34f7a67d84cb2c60c153d28ee879da5bb6a55a
--- /dev/null
+++ b/core/src/test/java/io/seata/core/rpc/netty/NettyClientChannelManagerTest.java
@@ -0,0 +1,180 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty;
+
+import io.netty.channel.Channel;
+import org.apache.commons.pool.impl.GenericKeyedObjectPool;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Netty client channel manager test.
+ *
+ * @author zhaojun
+ */
+@ExtendWith(MockitoExtension.class)
+class NettyClientChannelManagerTest {
+    
+    private NettyClientChannelManager channelManager;
+    
+    @Mock
+    private NettyPoolableFactory poolableFactory;
+    
+    @Mock
+    private Function<String, NettyPoolKey> poolKeyFunction;
+    
+    private NettyClientConfig nettyClientConfig = new NettyClientConfig();
+    
+    @Mock
+    private NettyPoolKey nettyPoolKey;
+    
+    @Mock
+    private Channel channel;
+    
+    @Mock
+    private Channel newChannel;
+    
+    @Mock
+    private GenericKeyedObjectPool keyedObjectPool;
+    
+    @BeforeEach
+    void setUp() {
+        channelManager = new NettyClientChannelManager(poolableFactory, poolKeyFunction, nettyClientConfig);
+    }
+    
+    @AfterEach
+    void tearDown() {
+    }
+    
+    @Test
+    void assertAcquireChannelFromPool() {
+        setupPoolFactory(nettyPoolKey, channel);
+        Channel actual = channelManager.acquireChannel("localhost");
+        verify(poolableFactory).makeObject(nettyPoolKey);
+        Assertions.assertEquals(actual, channel);
+    }
+    
+    private void setupPoolFactory(final NettyPoolKey nettyPoolKey, final Channel channel) {
+        when(poolKeyFunction.apply(anyString())).thenReturn(nettyPoolKey);
+        when(poolableFactory.makeObject(nettyPoolKey)).thenReturn(channel);
+        when(poolableFactory.validateObject(nettyPoolKey, channel)).thenReturn(true);
+    }
+    
+    @Test
+    void assertAcquireChannelFromCache() {
+        channelManager.getChannels().putIfAbsent("localhost", channel);
+        when(channel.isActive()).thenReturn(true);
+        Channel actual = channelManager.acquireChannel("localhost");
+        verify(poolableFactory, times(0)).makeObject(nettyPoolKey);
+        Assertions.assertEquals(actual, channel);
+    }
+    
+    @Test
+    void assertAcquireChannelFromPoolContainsInactiveCache() {
+        channelManager.getChannels().putIfAbsent("localhost", channel);
+        when(channel.isActive()).thenReturn(false);
+        setupPoolFactory(nettyPoolKey, newChannel);
+        Channel actual = channelManager.acquireChannel("localhost");
+        verify(poolableFactory).makeObject(nettyPoolKey);
+        Assertions.assertEquals(actual, newChannel);
+    }
+    
+    @Test
+    void assertReconnect() {
+        channelManager.getChannels().putIfAbsent("127.0.0.1:8091", channel);
+        when(channel.isActive()).thenReturn(true);
+        channelManager.reconnect("my_test_tx_group");
+        verify(channel).isActive();
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    void assertReleaseChannelWhichCacheIsEmpty() throws Exception {
+        setNettyClientKeyPool();
+        setUpReleaseChannel();
+        channelManager.releaseChannel(channel, "127.0.0.1:8091");
+        verify(keyedObjectPool).returnObject(nettyPoolKey, channel);
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    void assertReleaseCachedChannel() throws Exception {
+        setNettyClientKeyPool();
+        setUpReleaseChannel();
+        channelManager.getChannels().putIfAbsent("127.0.0.1:8091", channel);
+        channelManager.releaseChannel(channel, "127.0.0.1:8091");
+        assertTrue(channelManager.getChannels().isEmpty());
+        verify(keyedObjectPool).returnObject(nettyPoolKey, channel);
+    }
+    
+    @Test
+    @SuppressWarnings("unchecked")
+    void assertReleaseChannelNotEqualToCache() throws Exception {
+        setNettyClientKeyPool();
+        setUpReleaseChannel();
+        channelManager.getChannels().putIfAbsent("127.0.0.1:8091", newChannel);
+        channelManager.releaseChannel(channel, "127.0.0.1:8091");
+        assertEquals(1, channelManager.getChannels().size());
+        verify(keyedObjectPool).returnObject(nettyPoolKey, channel);
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void setUpReleaseChannel() {
+        ConcurrentMap<String, Object> channelLocks =
+            (ConcurrentMap<String, Object>) getFieldValue("channelLocks", channelManager);
+        channelLocks.putIfAbsent("127.0.0.1:8091", new Object());
+        ConcurrentMap<String, NettyPoolKey> poolKeyMap =
+            (ConcurrentMap<String, NettyPoolKey>) getFieldValue("poolKeyMap", channelManager);
+        poolKeyMap.putIfAbsent("127.0.0.1:8091", nettyPoolKey);
+    }
+    
+    private Object getFieldValue(final String fieldName, final Object targetObject) {
+        try {
+            Field field = targetObject.getClass().getDeclaredField(fieldName);
+            field.setAccessible(true);
+            return field.get(targetObject);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void setNettyClientKeyPool() {
+        try {
+            Field field = channelManager.getClass().getDeclaredField("nettyClientKeyPool");
+            field.setAccessible(true);
+            field.set(channelManager, keyedObjectPool);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/rpc/netty/RmRpcClientTest.java b/core/src/test/java/io/seata/core/rpc/netty/RmRpcClientTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f223992d44942274419acd3182ab035ac8b3f77
--- /dev/null
+++ b/core/src/test/java/io/seata/core/rpc/netty/RmRpcClientTest.java
@@ -0,0 +1,60 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Rm RPC client test.
+ *
+ * @author zhaojun
+ */
+class RmRpcClientTest {
+    
+    @Test
+    public void assertGetInstanceAfterDestroy() {
+        RmRpcClient oldClient = RmRpcClient.getInstance("ap", "group");
+        AtomicBoolean initialized = getInitializeStatus(oldClient);
+        oldClient.init();
+        assertTrue(initialized.get());
+        oldClient.destroy();
+        assertFalse(initialized.get());
+        RmRpcClient newClient = RmRpcClient.getInstance("ap", "group");
+        Assertions.assertNotEquals(oldClient, newClient);
+        initialized = getInitializeStatus(newClient);
+        assertFalse(initialized.get());
+        newClient.init();
+        assertTrue(initialized.get());
+        newClient.destroy();
+    }
+    
+    private AtomicBoolean getInitializeStatus(final RmRpcClient rmRpcClient) {
+        try {
+            Field field = rmRpcClient.getClass().getDeclaredField("initialized");
+            field.setAccessible(true);
+            return (AtomicBoolean) field.get(rmRpcClient);
+        } catch (Exception ex) {
+            throw new RuntimeException(ex.getMessage());
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/rpc/netty/TmRpcClientTest.java b/core/src/test/java/io/seata/core/rpc/netty/TmRpcClientTest.java
index 7a6169d1416e6868fc5e9179cdecc7717c0b17e4..ae1678efc2b0338bf61b8d3455e7c3033f11cd9d 100644
--- a/core/src/test/java/io/seata/core/rpc/netty/TmRpcClientTest.java
+++ b/core/src/test/java/io/seata/core/rpc/netty/TmRpcClientTest.java
@@ -15,12 +15,6 @@
  */
 package io.seata.core.rpc.netty;
 
-import java.lang.reflect.Field;
-import java.util.Map;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
 import io.netty.bootstrap.Bootstrap;
 import io.netty.bootstrap.ChannelFactory;
 import io.netty.channel.Channel;
@@ -30,6 +24,12 @@ import org.apache.commons.pool.impl.GenericKeyedObjectPool;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
 /**
  * The type Tm rpc client test.
  *
@@ -45,22 +45,23 @@ public class TmRpcClientTest {
     /**
      * Test get instance.
      *
-     * @throws Exception the exception
+     * @throws Exception the exceptionDataSourceManager.
      */
     @Test
     public void testGetInstance() throws Exception {
         String applicationId = "app 1";
         String transactionServiceGroup = "group A";
         TmRpcClient tmRpcClient = TmRpcClient.getInstance(applicationId, transactionServiceGroup);
-
+        Field nettyClientKeyPoolField = getDeclaredField(tmRpcClient.getClientChannelManager(), "nettyClientKeyPool");
+        nettyClientKeyPoolField.setAccessible(true);
+        GenericKeyedObjectPool nettyClientKeyPool = (GenericKeyedObjectPool) nettyClientKeyPoolField.get(tmRpcClient.getClientChannelManager());
         NettyClientConfig defaultNettyClientConfig = new NettyClientConfig();
-        GenericKeyedObjectPool.Config config = tmRpcClient.getNettyPoolConfig();
-        Assertions.assertEquals(defaultNettyClientConfig.getMaxPoolActive(), config.maxActive);
-        Assertions.assertEquals(defaultNettyClientConfig.getMinPoolIdle(), config.minIdle);
-        Assertions.assertEquals(defaultNettyClientConfig.getMaxAcquireConnMills(), config.maxWait);
-        Assertions.assertEquals(defaultNettyClientConfig.isPoolTestBorrow(), config.testOnBorrow);
-        Assertions.assertEquals(defaultNettyClientConfig.isPoolTestReturn(), config.testOnReturn);
-        Assertions.assertEquals(defaultNettyClientConfig.isPoolLifo(), config.lifo);
+        Assertions.assertEquals(defaultNettyClientConfig.getMaxPoolActive(), nettyClientKeyPool.getMaxActive());
+        Assertions.assertEquals(defaultNettyClientConfig.getMinPoolIdle(), nettyClientKeyPool.getMinIdle());
+        Assertions.assertEquals(defaultNettyClientConfig.getMaxAcquireConnMills(), nettyClientKeyPool.getMaxWait());
+        Assertions.assertEquals(defaultNettyClientConfig.isPoolTestBorrow(), nettyClientKeyPool.getTestOnBorrow());
+        Assertions.assertEquals(defaultNettyClientConfig.isPoolTestReturn(), nettyClientKeyPool.getTestOnReturn());
+        Assertions.assertEquals(defaultNettyClientConfig.isPoolLifo(), nettyClientKeyPool.getLifo());
     }
 
     /**
@@ -77,9 +78,12 @@ public class TmRpcClientTest {
         tmRpcClient.init();
 
         //check if attr of tmRpcClient object has been set success
-        Field bootstrapField = getDeclaredField(tmRpcClient, "bootstrap");
+        Field clientBootstrapField = getDeclaredField(tmRpcClient, "clientBootstrap");
+        clientBootstrapField.setAccessible(true);
+        RpcClientBootstrap clientBootstrap = (RpcClientBootstrap)clientBootstrapField.get(tmRpcClient);
+        Field bootstrapField = getDeclaredField(clientBootstrap, "bootstrap");
         bootstrapField.setAccessible(true);
-        Bootstrap bootstrap = (Bootstrap)bootstrapField.get(tmRpcClient);
+        Bootstrap bootstrap = (Bootstrap) bootstrapField.get(clientBootstrap);
 
         Assertions.assertNotNull(bootstrap);
         Field optionsField = getDeclaredField(bootstrap, "options");
diff --git a/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryProvider.java b/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryProvider.java
similarity index 96%
rename from discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryProvider.java
rename to discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryProvider.java
index 9f0a395718438abe74e7206af781e6ff37c43441..990d1a762807449bc2c5f01c7f2ca79adc772a63 100644
--- a/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryProvider.java
+++ b/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryProvider.java
@@ -13,7 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.discovery.registery.etcd;
+package io.seata.discovery.registry.etcd3;
 
 import io.seata.common.loader.LoadLevel;
 import io.seata.discovery.registry.RegistryProvider;
diff --git a/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryServiceImpl.java b/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java
similarity index 99%
rename from discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryServiceImpl.java
rename to discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java
index aaf3e476a25802026408d6c3481cf5825f76e66a..766411eecff484b79ecc3cfce1f5d7b0e0b84a28 100644
--- a/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registery/etcd/EtcdRegistryServiceImpl.java
+++ b/discovery/seata-discovery-etcd3/src/main/java/io/seata/discovery/registry/etcd3/EtcdRegistryServiceImpl.java
@@ -13,7 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.discovery.registery.etcd;
+package io.seata.discovery.registry.etcd3;
 
 
 import io.etcd.jetcd.ByteSequence;
diff --git a/discovery/seata-discovery-etcd3/src/main/resources/META-INF/services/io.seata.discovery.registry.RegistryProvider b/discovery/seata-discovery-etcd3/src/main/resources/META-INF/services/io.seata.discovery.registry.RegistryProvider
index 7d9b88d77ecf2a923dcbad50054f54f246d553c6..e193c9faf259ba85fb42754aa1b7e947f3d997f2 100644
--- a/discovery/seata-discovery-etcd3/src/main/resources/META-INF/services/io.seata.discovery.registry.RegistryProvider
+++ b/discovery/seata-discovery-etcd3/src/main/resources/META-INF/services/io.seata.discovery.registry.RegistryProvider
@@ -1 +1 @@
-io.seata.discovery.registery.etcd.EtcdRegistryProvider
\ No newline at end of file
+io.seata.discovery.registry.etcd3.EtcdRegistryProvider
\ No newline at end of file
diff --git a/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryProviderTest.java b/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryProviderTest.java
index 90ea08ed8b8ab9266c722e72efe50cb8ce48e55b..d5e5ea22ef808aedb171e9a0a1ff9f3126ab0ce7 100644
--- a/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryProviderTest.java
+++ b/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryProviderTest.java
@@ -15,8 +15,8 @@
  */
 package io.seata.discovery.registry.etcd;
 
-import io.seata.discovery.registery.etcd.EtcdRegistryProvider;
-import io.seata.discovery.registery.etcd.EtcdRegistryServiceImpl;
+import io.seata.discovery.registry.etcd3.EtcdRegistryProvider;
+import io.seata.discovery.registry.etcd3.EtcdRegistryServiceImpl;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryServiceImplTest.java b/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryServiceImplTest.java
index 3c2346a1ea3d6391bdc4052fe58492a69a633cbb..b920a88d2a93f56d8261b0218709b0519a91f91d 100644
--- a/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryServiceImplTest.java
+++ b/discovery/seata-discovery-etcd3/src/test/java/io/seata/discovery/registry/etcd/EtcdRegistryServiceImplTest.java
@@ -22,8 +22,8 @@ import io.etcd.jetcd.launcher.junit.EtcdClusterResource;
 import io.etcd.jetcd.options.DeleteOption;
 import io.etcd.jetcd.options.GetOption;
 import io.etcd.jetcd.watch.WatchResponse;
-import io.seata.discovery.registery.etcd.EtcdRegistryProvider;
-import io.seata.discovery.registery.etcd.EtcdRegistryServiceImpl;
+import io.seata.discovery.registry.etcd3.EtcdRegistryProvider;
+import io.seata.discovery.registry.etcd3.EtcdRegistryServiceImpl;
 import io.seata.discovery.registry.RegistryService;
 import org.junit.Rule;
 import org.junit.jupiter.api.AfterAll;
diff --git a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryServiceImpl.java b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryServiceImpl.java
index 30f8fea5093788a25a7ae2eae0a82435b37daf60..d57e4e84c647b0c5707ab3d5a5ed8a1f7e59ac78 100644
--- a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryServiceImpl.java
+++ b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryServiceImpl.java
@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import io.seata.common.exception.EurekaRegistryException;
+import io.seata.common.util.CollectionUtils;
 import io.seata.common.util.NetUtil;
 import io.seata.common.util.StringUtils;
 import io.seata.config.Configuration;
@@ -159,18 +160,17 @@ public class EurekaRegistryServiceImpl implements RegistryService<EurekaEventLis
     private void refreshCluster() throws EurekaRegistryException {
         Applications applications = getEurekaClient(false).getApplications();
         List<Application> list = applications.getRegisteredApplications();
-        if (list == null || list.isEmpty()) {
+        if (CollectionUtils.isEmpty(list)) {
             clusterAddressMap.clear();
             return;
         }
         for (Application app : list) {
             Set<InetSocketAddress> addressSet = new HashSet<>();
             List<InstanceInfo> instances = app.getInstances();
-            if (instances == null || instances.isEmpty()) {
-                break;
-            }
-            for (InstanceInfo instance : instances) {
-                addressSet.add(new InetSocketAddress(instance.getIPAddr(), instance.getPort()));
+            if (CollectionUtils.isNotEmpty(instances)) {
+                for (InstanceInfo instance : instances) {
+                    addressSet.add(new InetSocketAddress(instance.getIPAddr(), instance.getPort()));
+                }
             }
             clusterAddressMap.put(app.getName(), addressSet);
         }
diff --git a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryServiceImpl.java b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryServiceImpl.java
index a91e37a26b96ba04095b11c7b9dad3e476737744..d125077fa3ae696f95a3a2603147a49578e87c91 100644
--- a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryServiceImpl.java
+++ b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryServiceImpl.java
@@ -33,7 +33,6 @@ import io.seata.common.util.NetUtil;
 import io.seata.common.util.StringUtils;
 import io.seata.config.Configuration;
 import io.seata.config.ConfigurationFactory;
-
 import io.seata.discovery.registry.RegistryService;
 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.slf4j.Logger;
@@ -96,7 +95,7 @@ public class RedisRegistryServiceImpl implements RegistryService<RedisListener>
             redisConfig.setMaxTotal(maxTotal);
         }
         int maxWait = seataConfig.getInt(REDIS_FILEKEY_PREFIX + "max.wait",
-                seataConfig.getInt(REDIS_FILEKEY_PREFIX + "timeout", 0));
+            seataConfig.getInt(REDIS_FILEKEY_PREFIX + "timeout", 0));
         if (maxWait > 0) {
             redisConfig.setMaxWaitMillis(maxWait);
         }
@@ -204,13 +203,13 @@ public class RedisRegistryServiceImpl implements RegistryService<RedisListener>
             } finally {
                 jedis.close();
             }
-            if (null != instances) {
-                Set<InetSocketAddress> newAddressList = new HashSet<>();
+            if (null != instances && !instances.isEmpty()) {
+                Set<InetSocketAddress> newAddressSet = new HashSet<>();
                 for (Map.Entry<String, String> instance : instances.entrySet()) {
                     String serverAddr = instance.getKey();
-                    newAddressList.add(NetUtil.toInetSocketAddress(serverAddr));
+                    newAddressSet.add(NetUtil.toInetSocketAddress(serverAddr));
                 }
-                CLUSTER_ADDRESS_MAP.put(clusterName, newAddressList);
+                CLUSTER_ADDRESS_MAP.put(clusterName, newAddressSet);
             }
             subscribe(clusterName, new RedisListener() {
                 @Override
@@ -226,7 +225,7 @@ public class RedisRegistryServiceImpl implements RegistryService<RedisListener>
                             CLUSTER_ADDRESS_MAP.get(clusterName).remove(NetUtil.toInetSocketAddress(serverAddr));
                             break;
                         default:
-                            throw new ShouldNeverHappenException("unknow redis msg:" + msg);
+                            throw new ShouldNeverHappenException("unknown redis msg:" + msg);
                     }
                 }
             });
diff --git a/discovery/seata-discovery-sofa/src/test/io/seata/discovery/registry/sofa/SofaRegistryServiceImplTest.java b/discovery/seata-discovery-sofa/src/test/io/seata/discovery/registry/sofa/SofaRegistryServiceImplTest.java
index 9fae112de87e6f325e2b1bd67ebfb14e94d7a54c..2fcc937efb86c33b5269e163d7324c7584a4f78f 100644
--- a/discovery/seata-discovery-sofa/src/test/io/seata/discovery/registry/sofa/SofaRegistryServiceImplTest.java
+++ b/discovery/seata-discovery-sofa/src/test/io/seata/discovery/registry/sofa/SofaRegistryServiceImplTest.java
@@ -1,5 +1,5 @@
 /*
- *  Copyright 1999-2019 Seata.io Group.
+ * Copyright 1999-2019 Seata.io Group.
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
+
 package io.seata.discovery.registry.sofa;
 
 import com.alipay.sofa.registry.server.test.TestRegistryMain;
diff --git a/discovery/seata-discovery-zk/src/main/java/io/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java b/discovery/seata-discovery-zk/src/main/java/io/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
index cdbe910ad661322f0f5803dc07d3c04970d7d50f..bb18581d1edcf39540a34a22d460dead741f925f 100644
--- a/discovery/seata-discovery-zk/src/main/java/io/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
+++ b/discovery/seata-discovery-zk/src/main/java/io/seata/discovery/registry/zk/ZookeeperRegisterServiceImpl.java
@@ -37,6 +37,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import static io.seata.common.Constants.IP_PORT_SPLIT_CHAR;
 
@@ -113,7 +114,7 @@ public class ZookeeperRegisterServiceImpl implements RegistryService<IZkChildLis
             }
         }
     }
-    
+
     private boolean checkExists(String path) {
         return getClientInstance().exists(path);
     }
@@ -138,7 +139,7 @@ public class ZookeeperRegisterServiceImpl implements RegistryService<IZkChildLis
             getClientInstance().createPersistent(path);
         }
         getClientInstance().subscribeChildChanges(path, listener);
-        LISTENER_SERVICE_MAP.putIfAbsent(cluster, new ArrayList<>());
+        LISTENER_SERVICE_MAP.putIfAbsent(cluster, new CopyOnWriteArrayList<>());
         LISTENER_SERVICE_MAP.get(cluster).add(listener);
     }
 
@@ -207,17 +208,17 @@ public class ZookeeperRegisterServiceImpl implements RegistryService<IZkChildLis
             synchronized (ZookeeperRegisterServiceImpl.class) {
                 if (null == zkClient) {
                     zkClient = buildZkClient(FILE_CONFIG.getConfig(FILE_CONFIG_KEY_PREFIX + SERVER_ADDR_KEY),
-                            FILE_CONFIG.getInt(FILE_CONFIG_KEY_PREFIX + SESSION_TIME_OUT_KEY),
-                            FILE_CONFIG.getInt(FILE_CONFIG_KEY_PREFIX + CONNECT_TIME_OUT_KEY));
+                        FILE_CONFIG.getInt(FILE_CONFIG_KEY_PREFIX + SESSION_TIME_OUT_KEY),
+                        FILE_CONFIG.getInt(FILE_CONFIG_KEY_PREFIX + CONNECT_TIME_OUT_KEY));
                 }
             }
         }
         return zkClient;
     }
-    
+
     // visible for test.
     ZkClient buildZkClient(String address, int sessionTimeout, int connectTimeout) {
-        ZkClient zkClient = new ZkClient(address, sessionTimeout,connectTimeout);
+        ZkClient zkClient = new ZkClient(address, sessionTimeout, connectTimeout);
         if (!zkClient.exists(ROOT_PATH_WITHOUT_SUFFIX)) {
             zkClient.createPersistent(ROOT_PATH_WITHOUT_SUFFIX, true);
         }
diff --git a/metrics/README.md b/metrics/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..630e0b359e18ec147270619535f1587144438aec
--- /dev/null
+++ b/metrics/README.md
@@ -0,0 +1,131 @@
+### Metrics
+#### 设计思路
+1. Seata作为一个被集成的数据一致性框架,Metrics模块将尽可能少的使用第三方依赖以降低发生冲突的风险;
+2. Metrics模块将竭力争取更高的度量性能和更低的资源开销,尽可能降低开启后带来的副作用;
+3. 配置式,Metrics是否激活、数据如何发布,取决于对应的配置;
+4. 不使用Spring,使用SPI(Service Provider Interface)加载扩展;
+5. 初始仅发布核心Transaction相关指标,之后结合社区的需求,逐步完善运维方面的所有其他指标。
+
+#### 模块说明
+由2个核心API模块`seata-metrics-api`和`seata-metrics-core`,以及N个实现模块例如`seata-metrics-registry-compact`、`seata-metrics-exporter-prometheus`构成:
+
+- seata-metrics-api模块
+
+此模块是Metrics的核心,将作为Seata基础架构的一部分被TC、TM和RM引用,它内部**没有任何具体实现代码**,仅包含接口定义,定义的内容包括:
+1. Meter类接口:`Gauge`、`Counter`、`Timer`...
+2. 注册容器接口`Registry`
+3. Measurement数据导出接口`Exporter`
+
+>提示:Metrics本身在开源领域也已有很多实现,例如
+>1. [Netflix-Spectator](https://github.com/Netflix/spectator)
+>2. [Dropwizard-Metrics](https://github.com/dropwizard/metrics)
+>3. [Dubbo-Metrics](https://github.com/dubbo/dubbo-metrics)
+
+>它们有的轻而敏捷,有的重而强大,由于也是“实现”,因此不会纳入`seata-metrics-api`中,避免实现绑定。
+
+- seata-metrics-core模块
+
+Metrics核心模块,根据配置组织(加载)1个Registry和N个Exporter;
+
+- seata-metrics-registry-compact模块
+
+这是我们提供的默认(内置)的Registry实现,不使用其它Metrics开源库,轻量级的实现了以下四种Meter:
+
+| Meter类型  | 描述                                                                                                                         |
+| --------- | ------------------------------------------------------------ |
+| CompactGauge     | 单一最新值度量器                                                                                                                |
+| CompactCounter   | 单一累加度量器,可增可减                                                                                                         |
+| CompactSummary   | 多Measurement输出计数器,将输出`total`(合计)、`count`(计数)、`max`(最大)、`average`(合计/计数)和`tps`(合计/时间间隔),无单位  |
+| CompactTimer     | 多Measurement输出计时器,将输出`total`(合计)、`count`(计数)、`max`(最大)和`average`(合计/计数),支持微秒为单位累计              |
+
+其中包含的Registry,即`CompactRegistry`,它只有接受measure()方法调用的时候才计算度量值,因此计算窗口完全取决于Exporter的实现,故目前不太适合需要多Exporter的场景使用(如何扩展请参见后文)。
+
+>说明:
+>1. 未来可能增加更丰富复杂的度量器例如Histogram,这是一种可以本地统计聚合75th, 90th, 95th, 98th, 99th,99.9th...的度量器,适合某些场合,但需要更多内存。
+>2. 所有的计量器都将继承自Meter,所有的计量器执行measure()方法后,都将归一化的生成1或N个Measurement结果。
+
+- seata-metrics-exporter-prometheus模块
+
+Prometheus发布器`PrometheusExporter`,将度量数据同步给Prometheus。
+
+>说明:不同的监控系统,采集度量数据的方式不尽相同,例如Zabbix支持用zabbix-agent推送,Prometheus则推荐使用prometheus-server[拉取](https://prometheus.io/docs/practices/pushing/)的方式;同样数据交换协议也不同,因此往往需要逐一适配。
+
+#### 如何使用
+如果需要开启TC的Metrics,需要在其配置中增加配置项:
+```text
+## metrics settings
+metrics {
+  registry-type = "compact"
+  # multi exporters use comma divided
+  exporter-list = "prometheus"
+  exporter-prometheus-port = 9898
+}
+```
+
+启动TC,即可在`http://tc-server-ip:9898/metrics`上获取到Metrics的文本格式数据。
+
+>提示:默认使用`9898`端口,Prometheus已登记的端口列表[在此](https://github.com/prometheus/prometheus/wiki/Default-port-allocations),如果想更换端口,可通过`metrics.exporter-prometheus-port`配置修改。
+
+##### 下载并启动Prometheus
+下载完毕后,修改Prometheus的配置文件`prometheus.yml`,在`scrape_configs`中增加一项抓取Seata的度量数据:
+```yaml
+scrape_configs:
+  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
+  - job_name: 'prometheus'
+
+    # metrics_path defaults to '/metrics'
+    # scheme defaults to 'http'.
+
+    static_configs:
+    - targets: ['localhost:9090']
+
+  - job_name: 'seata'
+
+    # metrics_path defaults to '/metrics'
+    # scheme defaults to 'http'.
+
+    static_configs:
+    - targets: ['tc-server-ip:9898']
+```
+
+##### 查看数据输出
+推荐结合配置[Grafana](https://prometheus.io/docs/visualization/grafana/)获得更好的查询效果,初期Seata导出的Metrics包括:
+
+- TC :
+
+| Metrics    | 描述    |
+| ------ | --------- |
+| seata.transaction(role=tc,meter=counter,status=active/committed/rollback) | 当前活动中/已提交/已回滚的事务总数  |
+| seata.transaction(role=tc,meter=summary,statistic=count,status=committed/rollback) | 当前周期内提交/回滚的事务数  |
+| seata.transaction(role=tc,meter=summary,statistic=tps,status=committed/rollback) | 当前周期内提交/回滚的事务TPS(transaction per second) |
+| seata.transaction(role=tc,meter=timer,statistic=total,status=committed/rollback) | 当前周期内提交/回滚的事务耗时总和 |
+| seata.transaction(role=tc,meter=timer,statistic=count,status=committed/rollback) | 当前周期内提交/回滚的事务数  |
+| seata.transaction(role=tc,meter=timer,statistic=average,status=committed/rollback) | 当前周期内提交/回滚的事务平均耗时   |
+| seata.transaction(role=tc,meter=timer,statistic=max,status=committed/rollback) | 当前周期内提交/回滚的事务最大耗时 |
+
+>提示:seata.transaction(role=tc,meter=summary,statistic=count,status=committed/rollback)和seata.transaction(role=tc,meter=timer,statistic=count,status=committed/rollback)的值可能相同,但它们来源于两个不同的度量器。
+
+- TM:
+
+稍后实现,包括诸如:
+seata.transaction(role=tm,name={GlobalTransactionalName},meter=counter,status=active/committed/rollback) : 以GlobalTransactionalName为维度区分不同Transactional的状态。
+
+- RM:
+
+稍后实现,包括诸如:
+seata.transaction(role=rm,name={BranchTransactionalName},mode=at/mt,meter=counter,status=active/committed/rollback):以BranchTransactionalName为维度以及AT/MT维度区分不同分支Transactional的状态。
+
+#### 如何扩展
+如果有下面几种情况:
+
+1. 您不是使用Prometheus作为运维监控系统,但希望能够将Seata的Metrics数据集成进Dashboard中;
+
+您需要实现新的Exporter,例如如果需要对接Zabbix,创建`seata-metrics-exporter-zabbix`模块,然后在ExporterType中添加新的Exporter类型,最后在`metrics.exporter-list`中配置。
+
+2. 您需要更复杂强大的度量器类型,这些度量器在其他Metrics实现库中已有,希望集成这些第三方依赖直接使用;
+
+您可以不使用内置的CompactRegistry的实现,完全扩展一个新的Registry库,例如希望使用Netflix Spectator的实现,扩展名为`seata-metrics-registry-spectator`的模块,然后在RegistryType中添加新的Registry类型,开发完成后,设置`metrics.registry-type`为对应的类型。
+
+3. 您需要改变默认Metric的Measurement输出,例如在Timer中增加一个`min`或`sd`(方差);
+
+您可以修改对应Meter的实现,包括`measure()`方法返回的Measurement列表。
\ No newline at end of file
diff --git a/metrics/pom.xml b/metrics/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a4103502e7f676f7019904b2bbf4177a986482a7
--- /dev/null
+++ b/metrics/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>io.seata</groupId>
+        <artifactId>seata-parent</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>pom</packaging>
+    <artifactId>seata-metrics</artifactId>
+    <name>seata-metrics ${project.version}</name>
+
+    <modules>
+        <module>seata-metrics-all</module>
+        <module>seata-metrics-api</module>
+        <module>seata-metrics-core</module>
+        <module>seata-metrics-registry-compact</module>
+        <module>seata-metrics-exporter-prometheus</module>
+    </modules>
+
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-all/pom.xml b/metrics/seata-metrics-all/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6f1e2f258d37082199fe33753bb927bcf30c824e
--- /dev/null
+++ b/metrics/seata-metrics-all/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seata-metrics</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>seata-metrics-all</artifactId>
+    <name>seata-metrics-all ${project.version}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-registry-compact</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-exporter-prometheus</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-api/pom.xml b/metrics/seata-metrics-api/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..092685516c67398dca07902cf52c3eaf36a7c43e
--- /dev/null
+++ b/metrics/seata-metrics-api/pom.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seata-metrics</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seata-metrics-api</artifactId>
+    <name>seata-metrics-api ${project.version}</name>
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Clock.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Clock.java
new file mode 100644
index 0000000000000000000000000000000000000000..27fd8ae1c6df64f159b55a20a8d9b6c4ee3857db
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Clock.java
@@ -0,0 +1,25 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Clock interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Clock {
+    double getCurrentMilliseconds();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Counter.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Counter.java
new file mode 100644
index 0000000000000000000000000000000000000000..fa8d1f7a71ccd0bbc0223405e37b1bcb775ed7a2
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Counter.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Counter interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Counter extends Meter {
+    long increase(long value);
+
+    long decrease(long value);
+
+    long get();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Gauge.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Gauge.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5913dc4c49e2df679e31c9439a62dd0d585350b
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Gauge.java
@@ -0,0 +1,25 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Gauge interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Gauge<T extends Number> extends Meter {
+    T get();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Id.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Id.java
new file mode 100644
index 0000000000000000000000000000000000000000..32cfb689eb93a07432325047e3a568d7b1f45a39
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Id.java
@@ -0,0 +1,86 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+import java.util.Map.Entry;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.UUID;
+
+/**
+ * Meter id
+ *
+ * @author zhengyangyong
+ */
+public class Id {
+    private final UUID id;
+
+    private final String name;
+
+    private final SortedMap<String, String> tags;
+
+    public UUID getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Iterable<Entry<String, String>> getTags() {
+        return tags.entrySet();
+    }
+
+    public int getTagCount() {
+        return tags.size();
+    }
+
+    public Id(String name) {
+        this.id = UUID.randomUUID();
+        this.name = name;
+        this.tags = new TreeMap<>();
+    }
+
+    public Id withTag(String name, String value) {
+        this.tags.put(name, value);
+        return this;
+    }
+
+    public Id withTag(Iterable<Entry<String, String>> tags) {
+        if (tags != null) {
+            for (Entry<String, String> tag : tags) {
+                this.tags.put(tag.getKey(), tag.getValue());
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder(name);
+        builder.append("(");
+        if (tags.size() == 0) {
+            builder.append(")");
+            return builder.toString();
+        }
+        for (Entry<String, String> tag : tags.entrySet()) {
+            builder.append(String.format("%s=%s,", tag.getKey(), tag.getValue()));
+        }
+        builder.delete(builder.length() - 1, builder.length());
+        builder.append(")");
+        return builder.toString();
+    }
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/IdConstants.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/IdConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..6bc6fff56976d0cf5b76935dc1d1ebd796061a70
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/IdConstants.java
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Seata metrics constants for id
+ *
+ * @author zhengyangyong
+ */
+public class IdConstants {
+    public static final String SEATA_TRANSACTION = "seata.transaction";
+
+    public static final String NAME_KEY = "name";
+
+    public static final String ROLE_KEY = "role";
+
+    public static final String METER_KEY = "meter";
+
+    public static final String STATISTIC_KEY = "statistic";
+
+    public static final String STATUS_KEY = "status";
+
+    public static final String ROLE_VALUE_TC = "tc";
+
+    public static final String ROLE_VALUE_TM = "tm";
+
+    public static final String ROLE_VALUE_RM = "rm";
+
+    public static final String METER_VALUE_GAUGE = "gauge";
+
+    public static final String METER_VALUE_COUNTER = "counter";
+
+    public static final String METER_VALUE_SUMMARY = "summary";
+
+    public static final String METER_VALUE_TIMER = "timer";
+
+    public static final String STATISTIC_VALUE_COUNT = "count";
+
+    public static final String STATISTIC_VALUE_TOTAL = "total";
+
+    public static final String STATISTIC_VALUE_TPS = "tps";
+
+    public static final String STATISTIC_VALUE_MAX = "max";
+
+    public static final String STATISTIC_VALUE_AVERAGE = "average";
+
+    public static final String STATUS_VALUE_ACTIVE = "active";
+
+    public static final String STATUS_VALUE_COMMITTED = "committed";
+
+    public static final String STATUS_VALUE_ROLLBACKED = "rollbacked";
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Measurement.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Measurement.java
new file mode 100644
index 0000000000000000000000000000000000000000..544473e3ac0b0ea2ba2ff0f878a61bbf9bbe45b4
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Measurement.java
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Value of meter
+ *
+ * @author zhengyangyong
+ */
+public class Measurement {
+    private final Id id;
+
+    private final double timestamp;
+
+    private final double value;
+
+    public Id getId() {
+        return id;
+    }
+
+    public double getTimestamp() {
+        return timestamp;
+    }
+
+    public double getValue() {
+        return value;
+    }
+
+    public Measurement(Id id, double timestamp, double value) {
+        this.id = id;
+        this.timestamp = timestamp;
+        this.value = value;
+    }
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Meter.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Meter.java
new file mode 100644
index 0000000000000000000000000000000000000000..6da5e1b7a0618b86a83da42e765b31aa6fb06e49
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Meter.java
@@ -0,0 +1,27 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Meter interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Meter {
+    Id getId();
+
+    Iterable<Measurement> measure();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Summary.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Summary.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ffcbe3e3fc53f5cb0afac61be88a3bce2c46a8e
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Summary.java
@@ -0,0 +1,35 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Summary interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Summary extends Meter {
+    default void increase() {
+        increase(1);
+    }
+
+    void increase(long value);
+
+    long total();
+
+    long count();
+
+    double tps();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/SystemClock.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/SystemClock.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5084f831eb4cf2e8a702e7fddc6c2eafff0495f
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/SystemClock.java
@@ -0,0 +1,30 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+/**
+ * Default clock implement use system
+ *
+ * @author zhengyangyong
+ */
+public class SystemClock implements Clock {
+    public static final Clock INSTANCE = new SystemClock();
+
+    @Override
+    public double getCurrentMilliseconds() {
+        return System.currentTimeMillis();
+    }
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Timer.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Timer.java
new file mode 100644
index 0000000000000000000000000000000000000000..de6c6f2682d3debe1c0e54eb1d6a86a478f94d58
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/Timer.java
@@ -0,0 +1,35 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Default clock implement use system
+ *
+ * @author zhengyangyong
+ */
+public interface Timer extends Meter {
+    void record(long value, TimeUnit unit);
+
+    long count();
+
+    long total();
+
+    long max();
+
+    double average();
+}
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/exporter/Exporter.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/exporter/Exporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..75a5d56ad35c3ffa7343b18cd6b418c54152a290
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/exporter/Exporter.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.exporter;
+
+import java.io.Closeable;
+
+import io.seata.metrics.registry.Registry;
+
+/**
+ * Exporter interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Exporter extends Closeable {
+    void setRegistry(Registry registry);
+}
\ No newline at end of file
diff --git a/metrics/seata-metrics-api/src/main/java/io/seata/metrics/registry/Registry.java b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/registry/Registry.java
new file mode 100644
index 0000000000000000000000000000000000000000..9efaf5a31e484f1343fc6b068cca59975d734bbf
--- /dev/null
+++ b/metrics/seata-metrics-api/src/main/java/io/seata/metrics/registry/Registry.java
@@ -0,0 +1,42 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry;
+
+import java.util.function.Supplier;
+
+import io.seata.metrics.Counter;
+import io.seata.metrics.Gauge;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.Summary;
+import io.seata.metrics.Timer;
+
+/**
+ * Registry interface for metrics
+ *
+ * @author zhengyangyong
+ */
+public interface Registry {
+    <T extends Number> Gauge<T> getGauge(Id id, Supplier<T> supplier);
+
+    Counter getCounter(Id id);
+
+    Summary getSummary(Id id);
+
+    Timer getTimer(Id id);
+
+    Iterable<Measurement> measure();
+}
diff --git a/metrics/seata-metrics-core/pom.xml b/metrics/seata-metrics-core/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eb8e5a1ff8c9fcdfba50ba5f9b11b5204dc14f8d
--- /dev/null
+++ b/metrics/seata-metrics-core/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seata-metrics</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seata-metrics-core</artifactId>
+    <name>seata-metrics-core ${project.version}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-metrics-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterFactory.java b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..57ebaefe43308776d0c70041c7b192cf2211d3b6
--- /dev/null
+++ b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterFactory.java
@@ -0,0 +1,56 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.exporter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.util.StringUtils;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Exporter Factory for load all configured exporters
+ *
+ * @author zhengyangyong
+ */
+public class ExporterFactory {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExporterFactory.class);
+
+    public static List<Exporter> getInstanceList() {
+        List<Exporter> exporters = new ArrayList<>();
+        String exporterTypeNameList = ConfigurationFactory.getInstance().getConfig(
+            ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_EXPORTER_LIST, null);
+        if (!StringUtils.isNullOrEmpty(exporterTypeNameList)) {
+            String[] exporterTypeNames = exporterTypeNameList.split(",");
+            for (String exporterTypeName : exporterTypeNames) {
+                ExporterType exporterType;
+                try {
+                    exporterType = ExporterType.getType(exporterTypeName);
+                    exporters.add(
+                        EnhancedServiceLoader.load(Exporter.class, Objects.requireNonNull(exporterType).name()));
+                } catch (Exception exx) {
+                    LOGGER.error("not support metrics exporter type: " + exporterTypeName, exx);
+                }
+            }
+        }
+        return exporters;
+    }
+}
diff --git a/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterType.java b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterType.java
new file mode 100644
index 0000000000000000000000000000000000000000..f23f7e4dbc5ca9c778fd9bc0ca09e5bc14087752
--- /dev/null
+++ b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/exporter/ExporterType.java
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.exporter;
+
+import io.seata.common.exception.NotSupportYetException;
+
+/**
+ * Supported metrics exporter type
+ *
+ * @author zhengyangyong
+ */
+public enum ExporterType {
+    /**
+     * Export metrics data to Prometheus
+     */
+    Prometheus;
+
+    public static ExporterType getType(String name) {
+        if (Prometheus.name().equalsIgnoreCase(name)) {
+            return Prometheus;
+        } else {
+            throw new NotSupportYetException("unsupported type:" + name);
+        }
+    }
+}
diff --git a/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryFactory.java b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..2123eee9dc1d1a22571fcdc8c7ecf6b7036587a2
--- /dev/null
+++ b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryFactory.java
@@ -0,0 +1,46 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry;
+
+import java.util.Objects;
+
+import io.seata.common.exception.NotSupportYetException;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.util.StringUtils;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+
+/**
+ * Registry Factory for load configured metrics registry
+ *
+ * @author zhengyangyong
+ */
+public class RegistryFactory {
+    public static Registry getInstance() {
+        RegistryType registryType;
+        String registryTypeName = ConfigurationFactory.getInstance().getConfig(
+            ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_REGISTRY_TYPE, null);
+        if (!StringUtils.isNullOrEmpty(registryTypeName)) {
+            try {
+                registryType = RegistryType.getType(registryTypeName);
+            } catch (Exception exx) {
+                throw new NotSupportYetException("not support metrics registry type: " + registryTypeName);
+            }
+            return EnhancedServiceLoader.load(Registry.class, Objects.requireNonNull(registryType).name());
+        }
+        return null;
+    }
+}
diff --git a/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryType.java b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryType.java
new file mode 100644
index 0000000000000000000000000000000000000000..51168d48eeb0853b39521d32b9b84ced580bcb60
--- /dev/null
+++ b/metrics/seata-metrics-core/src/main/java/io/seata/metrics/registry/RegistryType.java
@@ -0,0 +1,38 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry;
+
+import io.seata.common.exception.NotSupportYetException;
+
+/**
+ * Supported metrics registry type
+ *
+ * @author zhengyangyong
+ */
+public enum RegistryType {
+    /**
+     * Built-in compact metrics registry
+     */
+    Compact;
+
+    public static RegistryType getType(String name) {
+        if (Compact.name().equalsIgnoreCase(name)) {
+            return Compact;
+        } else {
+            throw new NotSupportYetException("unsupported type:" + name);
+        }
+    }
+}
diff --git a/metrics/seata-metrics-exporter-prometheus/pom.xml b/metrics/seata-metrics-exporter-prometheus/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f6b410548695cf04e1648a66497c6442afd59835
--- /dev/null
+++ b/metrics/seata-metrics-exporter-prometheus/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seata-metrics</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seata-metrics-exporter-prometheus</artifactId>
+    <name>seata-metrics-exporter-prometheus ${project.version}</name>
+
+    <properties>
+        <prometheus.client.version>0.6.0</prometheus.client.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>io.prometheus</groupId>
+            <artifactId>simpleclient_httpserver</artifactId>
+            <version>${prometheus.client.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-exporter-prometheus/src/main/java/io/seata/metrics/exporter/prometheus/PrometheusExporter.java b/metrics/seata-metrics-exporter-prometheus/src/main/java/io/seata/metrics/exporter/prometheus/PrometheusExporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..f9ac69bbd7927edccd1f4ca4394487c5b9568bbd
--- /dev/null
+++ b/metrics/seata-metrics-exporter-prometheus/src/main/java/io/seata/metrics/exporter/prometheus/PrometheusExporter.java
@@ -0,0 +1,95 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.exporter.prometheus;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import io.prometheus.client.Collector;
+import io.prometheus.client.Collector.MetricFamilySamples.Sample;
+import io.prometheus.client.exporter.HTTPServer;
+import io.seata.common.loader.LoadLevel;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.exporter.Exporter;
+import io.seata.metrics.registry.Registry;
+
+/**
+ * Exporter for Prometheus
+ *
+ * @author zhengyangyong
+ */
+@LoadLevel(name = "Prometheus", order = 1)
+public class PrometheusExporter extends Collector implements Collector.Describable, Exporter {
+    private static final String METRICS_EXPORTER_PROMETHEUS_PORT = "exporter-prometheus-port";
+
+    private final HTTPServer server;
+
+    private Registry registry;
+
+    public PrometheusExporter() throws IOException {
+        int port = ConfigurationFactory.getInstance().getInt(
+            ConfigurationKeys.METRICS_PREFIX + METRICS_EXPORTER_PROMETHEUS_PORT, 9898);
+        this.server = new HTTPServer(port, true);
+        this.register();
+    }
+
+    @Override
+    public void setRegistry(Registry registry) {
+        this.registry = registry;
+    }
+
+    @Override
+    public List<MetricFamilySamples> collect() {
+        List<MetricFamilySamples> familySamples = new ArrayList<>();
+        if (registry != null) {
+            Iterable<Measurement> measurements = registry.measure();
+            List<Sample> samples = new ArrayList<>();
+            measurements.forEach(measurement -> samples.add(convertMeasurementToSample(measurement)));
+
+            if (samples.size() != 0) {
+                familySamples.add(new MetricFamilySamples("seata", Type.UNTYPED, "seata", samples));
+            }
+        }
+        return familySamples;
+    }
+
+    private Sample convertMeasurementToSample(Measurement measurement) {
+        String prometheusName = measurement.getId().getName().replace(".", "_");
+        List<String> labelNames = new ArrayList<>();
+        List<String> labelValues = new ArrayList<>();
+        for (Entry<String, String> tag : measurement.getId().getTags()) {
+            labelNames.add(tag.getKey());
+            labelValues.add(tag.getValue());
+        }
+        return new Sample(prometheusName, labelNames, labelValues, measurement.getValue(),
+            (long)measurement.getTimestamp());
+    }
+
+    @Override
+    public List<MetricFamilySamples> describe() {
+        return collect();
+    }
+
+    @Override
+    public void close() {
+        server.stop();
+    }
+
+}
\ No newline at end of file
diff --git a/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/services/io.seata.metrics.exporter.Exporter b/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/services/io.seata.metrics.exporter.Exporter
new file mode 100644
index 0000000000000000000000000000000000000000..ee06c43ac1732ed4181fc81ba1d201e2492c0143
--- /dev/null
+++ b/metrics/seata-metrics-exporter-prometheus/src/main/resources/META-INF/services/io.seata.metrics.exporter.Exporter
@@ -0,0 +1 @@
+io.seata.metrics.exporter.prometheus.PrometheusExporter
\ No newline at end of file
diff --git a/metrics/seata-metrics-registry-compact/pom.xml b/metrics/seata-metrics-registry-compact/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..48b5dd5e11d97500fb000bd681bc74207330c413
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/pom.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~  Copyright 1999-2019 Seata.io Group.
+  ~
+  ~  Licensed 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>seata-metrics</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seata-metrics-registry-compact</artifactId>
+    <name>seata-metrics-registry-compact ${project.version}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-metrics-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactCounter.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactCounter.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8ac6f2995ca4914c04654e989616913ef386f6f
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactCounter.java
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicLong;
+
+import io.seata.metrics.Clock;
+import io.seata.metrics.Counter;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.SystemClock;
+
+/**
+ * Compact Counter implement with AtomicLong
+ *
+ * @author zhengyangyong
+ */
+public class CompactCounter implements Counter {
+    private final Id id;
+
+    private final AtomicLong counter;
+
+    private final Clock clock;
+
+    public CompactCounter(Id id) {
+        this(id, SystemClock.INSTANCE);
+    }
+
+    public CompactCounter(Id id, Clock clock) {
+        this.id = id;
+        this.counter = new AtomicLong(0);
+        this.clock = clock;
+    }
+
+    @Override
+    public Id getId() {
+        return id;
+    }
+
+    @Override
+    public long increase(long value) {
+        return counter.addAndGet(value);
+    }
+
+    @Override
+    public long decrease(long value) {
+        return increase(-1 * value);
+    }
+
+    @Override
+    public long get() {
+        return counter.get();
+    }
+
+    @Override
+    public Iterable<Measurement> measure() {
+        return Collections.singletonList(new Measurement(id, clock.getCurrentMilliseconds(), counter.get()));
+    }
+}
\ No newline at end of file
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactGauge.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactGauge.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7d9e329854c58bcf47992c98a54e95c4b7e781f
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactGauge.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.Collections;
+import java.util.function.Supplier;
+
+import io.seata.metrics.Clock;
+import io.seata.metrics.Gauge;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.SystemClock;
+
+/**
+ * Compact Gauge implement with Supplier
+ *
+ * @author zhengyangyong
+ */
+public class CompactGauge<T extends Number> implements Gauge<T> {
+    private final Id id;
+
+    private final Supplier<T> supplier;
+
+    private final Clock clock;
+
+    public CompactGauge(Id id, Supplier<T> supplier) {
+        this(id, supplier, SystemClock.INSTANCE);
+    }
+
+    public CompactGauge(Id id, Supplier<T> supplier, Clock clock) {
+        this.id = id;
+        this.supplier = supplier;
+        this.clock = clock;
+    }
+
+    @Override
+    public T get() {
+        return supplier.get();
+    }
+
+    @Override
+    public Id getId() {
+        return id;
+    }
+
+    @Override
+    public Iterable<Measurement> measure() {
+        return Collections.singletonList(new Measurement(id, clock.getCurrentMilliseconds(), get().doubleValue()));
+    }
+}
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactRegistry.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactRegistry.java
new file mode 100644
index 0000000000000000000000000000000000000000..0fc4d7dc58808fc6a4735a2fcc44ef21907a7602
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactRegistry.java
@@ -0,0 +1,74 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Supplier;
+
+import io.seata.common.loader.LoadLevel;
+import io.seata.metrics.Counter;
+import io.seata.metrics.Gauge;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.Meter;
+import io.seata.metrics.registry.Registry;
+import io.seata.metrics.Summary;
+import io.seata.metrics.Timer;
+
+/**
+ * Compact Registry implement, this registry only compute all Measurements when call measure method and do not cache
+ *
+ * @author zhengyangyong
+ */
+@LoadLevel(name = "Compact", order = 1)
+public class CompactRegistry implements Registry {
+    private static final Map<UUID, Meter> METERS = new ConcurrentHashMap<>();
+
+    @Override
+    public <T extends Number> Gauge<T> getGauge(Id id, Supplier<T> supplier) {
+        return (Gauge<T>)CompactRegistry.METERS.computeIfAbsent(id.getId(), key -> new CompactGauge<>(id, supplier));
+    }
+
+    @Override
+    public Counter getCounter(Id id) {
+        return (Counter)CompactRegistry.METERS.computeIfAbsent(id.getId(), key -> new CompactCounter(id));
+    }
+
+    @Override
+    public Summary getSummary(Id id) {
+        return (Summary)CompactRegistry.METERS.computeIfAbsent(id.getId(), key -> new CompactSummary(id));
+    }
+
+    @Override
+    public Timer getTimer(Id id) {
+        return (Timer)CompactRegistry.METERS.computeIfAbsent(id.getId(), key -> new CompactTimer(id));
+    }
+
+    @Override
+    public Iterable<Measurement> measure() {
+        List<Measurement> measurements = new ArrayList<>();
+        if (CompactRegistry.METERS.size() == 0) {
+            return measurements;
+        }
+        CompactRegistry.METERS.values().iterator().forEachRemaining(
+            meter -> meter.measure().forEach(measurements::add));
+        return measurements;
+    }
+}
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactSummary.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactSummary.java
new file mode 100644
index 0000000000000000000000000000000000000000..db77fa1eab2934ebeecc9b88837de77051a5d47e
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactSummary.java
@@ -0,0 +1,95 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.Arrays;
+
+import io.seata.metrics.Clock;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.Summary;
+import io.seata.metrics.SystemClock;
+import io.seata.metrics.IdConstants;
+
+/**
+ * Compact Summary implement with SummaryValue
+ *
+ * @author zhengyangyong
+ */
+public class CompactSummary implements Summary {
+    private final Id id;
+
+    private final Id countId;
+
+    private final Id totalId;
+
+    private final Id tpsId;
+
+    private volatile SummaryValue value;
+
+    private final Clock clock;
+
+    public CompactSummary(Id id) {
+        this(id, SystemClock.INSTANCE);
+    }
+
+    public CompactSummary(Id id, Clock clock) {
+        this.id = id;
+        this.countId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_COUNT);
+        this.totalId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TOTAL);
+        this.tpsId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TPS);
+        this.value = new SummaryValue(clock.getCurrentMilliseconds());
+        this.clock = clock;
+    }
+
+    @Override
+    public Id getId() {
+        return id;
+    }
+
+    @Override
+    public void increase(long value) {
+        this.value.increase(value);
+    }
+
+    @Override
+    public long total() {
+        return this.value.getTotal();
+    }
+
+    @Override
+    public long count() {
+        return this.value.getCount();
+    }
+
+    @Override
+    public double tps() {
+        return this.value.getTps(clock.getCurrentMilliseconds());
+    }
+
+    @Override
+    public Iterable<Measurement> measure() {
+        SummaryValue value = this.value;
+        double time = clock.getCurrentMilliseconds();
+        this.value = new SummaryValue(time);
+        return Arrays.asList(new Measurement(countId, time, value.getCount()),
+            new Measurement(totalId, time, value.getTotal()),
+            new Measurement(tpsId, time, value.getTps(time)));
+    }
+}
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactTimer.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactTimer.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c0931372ee1d22aeabb6f7ffecd2f9d452f9f2f
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/CompactTimer.java
@@ -0,0 +1,107 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import io.seata.metrics.Clock;
+import io.seata.metrics.Id;
+import io.seata.metrics.Measurement;
+import io.seata.metrics.SystemClock;
+import io.seata.metrics.Timer;
+import io.seata.metrics.IdConstants;
+
+/**
+ * Compact Timer implement with TimerValue
+ *
+ * @author zhengyangyong
+ */
+public class CompactTimer implements Timer {
+    private final Id id;
+
+    private final Id countId;
+
+    private final Id totalId;
+
+    private final Id maxId;
+
+    private final Id averageId;
+
+    private volatile TimerValue value;
+
+    private final Clock clock;
+
+    public CompactTimer(Id id) {
+        this(id, SystemClock.INSTANCE);
+    }
+
+    public CompactTimer(Id id, Clock clock) {
+        this.id = id;
+        this.countId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_COUNT);
+        this.totalId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_TOTAL);
+        this.maxId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_MAX);
+        this.averageId = new Id(id.getName()).withTag(id.getTags())
+            .withTag(IdConstants.STATISTIC_KEY, IdConstants.STATISTIC_VALUE_AVERAGE);
+        this.value = new TimerValue();
+        this.clock = clock;
+    }
+
+    @Override
+    public Id getId() {
+        return id;
+    }
+
+    @Override
+    public void record(long value, TimeUnit unit) {
+        this.value.record(value, unit);
+    }
+
+    @Override
+    public long count() {
+        return this.value.getCount();
+    }
+
+    @Override
+    public long total() {
+        return this.value.getTotal();
+    }
+
+    @Override
+    public long max() {
+        return this.value.getMax();
+    }
+
+    @Override
+    public double average() {
+        return this.value.getAverage();
+    }
+
+    @Override
+    public Iterable<Measurement> measure() {
+        //reset value when measure
+        double time = clock.getCurrentMilliseconds();
+        TimerValue value = this.value;
+        this.value = new TimerValue();
+        return Arrays.asList(new Measurement(countId, time, value.getCount()),
+            new Measurement(totalId, time, value.getTotal() * 0.001),
+            new Measurement(maxId, time, value.getMax() * 0.001),
+            new Measurement(averageId, time, value.getAverage() * 0.001));
+    }
+}
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/SummaryValue.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/SummaryValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..cc1fa37dd8b00c9f43cf95df3c397cc0f45323f2
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/SummaryValue.java
@@ -0,0 +1,64 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.concurrent.atomic.LongAdder;
+
+/**
+ * Record container for CompactSummary
+ *
+ * @author zhengyangyong
+ */
+public class SummaryValue {
+    private final LongAdder count;
+
+    private final LongAdder total;
+
+    private final double startMilliseconds;
+
+    public long getCount() {
+        return count.longValue();
+    }
+
+    public long getTotal() {
+        return total.longValue();
+    }
+
+    public double getTps(double currentMilliseconds) {
+        if (currentMilliseconds <= startMilliseconds) {
+            return 0;
+        }
+        return total.doubleValue() / (currentMilliseconds - startMilliseconds) * 1000.0;
+    }
+
+    public SummaryValue(double startMilliseconds) {
+        this.count = new LongAdder();
+        this.total = new LongAdder();
+        this.startMilliseconds = startMilliseconds;
+    }
+
+    public void increase() {
+        this.increase(1);
+    }
+
+    public void increase(long value) {
+        if (value <= 0) {
+            return;
+        }
+        this.count.increment();
+        this.total.add(value);
+    }
+}
diff --git a/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/TimerValue.java b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/TimerValue.java
new file mode 100644
index 0000000000000000000000000000000000000000..96f08206f0d169561835733328be7e0f5e2d9a5a
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/java/io/seata/metrics/registry/compact/TimerValue.java
@@ -0,0 +1,67 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.metrics.registry.compact;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.LongAdder;
+
+/**
+ * Record container for CompactTimer
+ *
+ * @author zhengyangyong
+ */
+public class TimerValue {
+    private final LongAdder count;
+
+    private final LongAdder total;
+
+    private final AtomicLong max;
+
+    public long getCount() {
+        return count.longValue();
+    }
+
+    public long getTotal() {
+        return total.longValue();
+    }
+
+    public long getMax() {
+        return max.get();
+    }
+
+    public double getAverage() {
+        double count = this.count.doubleValue();
+        double total = this.total.doubleValue();
+        return count == 0 ? 0 : total / count;
+    }
+
+    public TimerValue() {
+        this.count = new LongAdder();
+        this.total = new LongAdder();
+        this.max = new AtomicLong(0);
+    }
+
+    public void record(long value, TimeUnit unit) {
+        if (value <= 0) {
+            return;
+        }
+        long changeValue = unit == TimeUnit.MICROSECONDS ? value : TimeUnit.MICROSECONDS.convert(value, unit);
+        this.count.increment();
+        this.total.add(changeValue);
+        this.max.accumulateAndGet(changeValue, Math::max);
+    }
+}
\ No newline at end of file
diff --git a/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/services/io.seata.metrics.registry.Registry b/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/services/io.seata.metrics.registry.Registry
new file mode 100644
index 0000000000000000000000000000000000000000..83dfd94efff23e7d104670267d2040c3dbe143e8
--- /dev/null
+++ b/metrics/seata-metrics-registry-compact/src/main/resources/META-INF/services/io.seata.metrics.registry.Registry
@@ -0,0 +1 @@
+io.seata.metrics.registry.compact.CompactRegistry
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 901cbe2a0fae7a20fc740086126c03b58151a234..85b8d19d432da9bec80fe3fba42cbde95a20ec76 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,8 @@
         <module>tcc</module>
         <module>test</module>
         <module>tm</module>
+        <module>metrics</module>
+        <module>codec</module>
     </modules>
     <packaging>pom</packaging>
 
@@ -83,7 +85,7 @@
 
     <properties>
         <!-- seata version -->
-        <revision>0.6.1</revision>
+        <revision>0.7.0</revision>
 
         <!-- Compiler settings properties -->
         <maven.compiler.source>1.8</maven.compiler.source>
@@ -105,7 +107,7 @@
 
         <!-- for test -->
         <junit-jupiter.version>5.4.2</junit-jupiter.version>
-        <mockito-core.version>2.23.4</mockito-core.version>
+        <mockito.version>2.23.4</mockito.version>
         <assertj-core.version>3.12.2</assertj-core.version>
         <junit-platform-launcher.version>1.4.2</junit-platform-launcher.version>
 
@@ -134,7 +136,13 @@
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
-            <version>${mockito-core.version}</version>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-junit-jupiter</artifactId>
+            <version>${mockito.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
@@ -224,6 +232,41 @@
             </distributionManagement>
 
         </profile>
+        <profile>
+            <id>licenseCheck</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>license-maven-plugin</artifactId>
+                        <version>1.20</version>
+                        <executions>
+                            <execution>
+                                <id>license-check</id>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-third-party</goal>
+                                </goals>
+                                <configuration>
+                                    <includeOptional>false</includeOptional>
+                                    <useMissingFile>false</useMissingFile>
+                                    <failOnMissing>false</failOnMissing>
+                                    <licenseMerges>
+                                        <licenseMerge>Apache License, Version 2.0|The Apache Software License, Version
+                                            2.0|ASF 2.0|Apache 2|Apache-2.0|Apache 2.0 License|Apache 2.0|Apache License v2.0|Apache License 2.0|The Apache License, Version 2.0|The Apache Software License, Version 2.0
+                                        </licenseMerge>
+                                        <licenseMerge>The MIT License|MIT License</licenseMerge>
+                                        <licenseMerge>The 3-Clause BSD License|New BSD License|3-Clause BSD
+                                            License|BSD|3-Clause BSD License|The New BSD License
+                                        </licenseMerge>
+                                    </licenseMerges>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
     </profiles>
 
     <build>
@@ -269,6 +312,9 @@
                         <ruleset>rulesets/java/ali-other.xml</ruleset>
                         <ruleset>rulesets/java/ali-set.xml</ruleset>
                     </rulesets>
+                    <excludes>
+                        <exclude>**/generated/*.java</exclude>
+                    </excludes>
                 </configuration>
                 <executions>
                     <execution>
@@ -364,6 +410,9 @@
                         <include>**/src/main/java/**</include>
                         <include>**/src/test/java/**</include>
                     </includes>
+                    <excludes>
+                        <exclude>**/generated/**</exclude>
+                    </excludes>
                     <strictCheck>true</strictCheck>
                     <mapping>
                         <java>SLASHSTAR_STYLE</java>
@@ -384,6 +433,7 @@
                             <consoleOutput>true</consoleOutput>
                             <failsOnError>false</failsOnError>
                             <failOnViolation>false</failOnViolation>
+                            <excludes>**/generated/**</excludes>
                         </configuration>
                         <goals>
                             <goal>check</goal>
diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml
index 3b1a0435f453e409a57e89783e30dbe59943b88d..6bd8c2a57c2906e0782f91151e8ab66980a91d1a 100644
--- a/rm-datasource/pom.xml
+++ b/rm-datasource/pom.xml
@@ -47,6 +47,18 @@
             <groupId>com.github.ben-manes.caffeine</groupId>
             <artifactId>caffeine</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.protostuff</groupId>
+            <artifactId>protostuff-runtime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>commons-dbcp</groupId>
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/AbstractPreparedStatementProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/AbstractPreparedStatementProxy.java
index 40adc924fa65e190a72eec5b9e1acc8b9a2a8fab..ff114fc2e376e7957a17cb7a3ea8e56bf56e8c9b 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/AbstractPreparedStatementProxy.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/AbstractPreparedStatementProxy.java
@@ -15,6 +15,8 @@
  */
 package io.seata.rm.datasource;
 
+import io.seata.common.exception.NotSupportYetException;
+import io.seata.core.context.RootContext;
 import java.io.InputStream;
 import java.io.Reader;
 import java.math.BigDecimal;
@@ -246,7 +248,10 @@ public abstract class AbstractPreparedStatementProxy extends StatementProxy<Prep
 
     @Override
     public void addBatch() throws SQLException {
-
+        if (RootContext.inGlobalTransaction()) {
+            throw new NotSupportYetException();
+        }
+        targetStatement.addBatch();
     }
 
     @Override
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java
index 5eb96a49ada14749c39e18a54bcfe8e5b4ee004b..a32cfce07af473f9a9bfe8421c655f1a59374ba6 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/ConnectionContext.java
@@ -154,14 +154,12 @@ public class ConnectionContext {
         this.branchId = branchId;
     }
 
+
     /**
      * Reset.
      */
-    void reset() {
-        xid = null;
-        branchId = null;
-        lockKeysBuffer.clear();
-        sqlUndoItemsBuffer.clear();
+    void reset(){
+        this.reset(null);
     }
 
     /**
@@ -172,6 +170,7 @@ public class ConnectionContext {
     void reset(String xid) {
         this.xid = xid;
         branchId = null;
+        this.isGlobalLockRequire = false;
         lockKeysBuffer.clear();
         sqlUndoItemsBuffer.clear();
     }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/DataCompareUtils.java b/rm-datasource/src/main/java/io/seata/rm/datasource/DataCompareUtils.java
index 2485519f8a4e25772f4ebbf79170f392767d0e66..5ee08ac46c8f932ebc7afb9631fec0a9850219bf 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/DataCompareUtils.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/DataCompareUtils.java
@@ -21,7 +21,10 @@ import io.seata.rm.datasource.sql.struct.Field;
 import io.seata.rm.datasource.sql.struct.Row;
 import io.seata.rm.datasource.sql.struct.TableMeta;
 import io.seata.rm.datasource.sql.struct.TableRecords;
+import io.seata.rm.datasource.undo.UndoLogManager;
+import io.seata.rm.datasource.undo.parser.FastjsonUndoLogParser;
 
+import java.math.BigDecimal;
 import java.sql.Timestamp;
 import java.sql.Types;
 import java.util.HashMap;
@@ -57,13 +60,9 @@ public class DataCompareUtils {
                         if (f1.getValue() == null) {
                             return false;
                         } else {
-                            int f0Type = f0.getType();
-                            int f1Type = f1.getType();
-                            if (f0Type == Types.TIMESTAMP && f0.getValue().getClass().equals(String.class)) {
-                                f0.setValue(Timestamp.valueOf(f0.getValue().toString()));
-                            }
-                            if (f1Type == Types.TIMESTAMP && f1.getValue().getClass().equals(String.class)) {
-                                f1.setValue(Timestamp.valueOf(f1.getValue().toString()));
+                            String currentSerializer = UndoLogManager.getCurrentSerializer();
+                            if (StringUtils.equals(currentSerializer, FastjsonUndoLogParser.NAME)) {
+                                convertType(f0, f1);
                             }
                             return f0.getValue().equals(f1.getValue());
                         }
@@ -75,6 +74,23 @@ public class DataCompareUtils {
         }
     }
 
+    private static void convertType(Field f0, Field f1) {
+        int f0Type = f0.getType();
+        int f1Type = f1.getType();
+        if (f0Type == Types.TIMESTAMP && f0.getValue().getClass().equals(String.class)) {
+            f0.setValue(Timestamp.valueOf(f0.getValue().toString()));
+        }
+        if (f1Type == Types.TIMESTAMP && f1.getValue().getClass().equals(String.class)) {
+            f1.setValue(Timestamp.valueOf(f1.getValue().toString()));
+        }
+        if (f0Type == Types.DECIMAL && f0.getValue().getClass().equals(Integer.class)) {
+            f0.setValue(new BigDecimal(f0.getValue().toString()));
+        }
+        if (f1Type == Types.DECIMAL && f1.getValue().getClass().equals(Integer.class)) {
+            f1.setValue(new BigDecimal(f1.getValue().toString()));
+        }
+    }
+
     /**
      * Is image equals.
      *
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceManager.java b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceManager.java
index b1ad1b7e9b62dd1b261b43efca4154a0ec329198..2f4b0e87aac8fcaf319cd4aed4237c5269618c5f 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceManager.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceManager.java
@@ -176,6 +176,9 @@ public class DataSourceManager extends AbstractResourceManager implements Initia
         try {
             UndoLogManager.undo(dataSourceProxy, xid, branchId);
         } catch (TransactionException te) {
+            if (LOGGER.isInfoEnabled()){
+                LOGGER.info("branchRollback failed reason [{}]", te.getMessage());
+            }
             if (te.getCode() == TransactionExceptionCode.BranchRollbackFailed_Unretriable) {
                 return BranchStatus.PhaseTwo_RollbackFailed_Unretryable;
             } else {
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java
index 32ffbe98547b4036748ea79212b6435f6c4f92de..fbcd24be80ac7abd1fdce2c586dd35ab284d1c01 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/DataSourceProxy.java
@@ -110,7 +110,11 @@ public class DataSourceProxy extends AbstractDataSourceProxy implements Resource
 
     @Override
     public String getResourceId() {
-        return jdbcUrl;
+        if (jdbcUrl.contains("?")) {
+            return jdbcUrl.substring(0, jdbcUrl.indexOf("?"));
+        } else {
+            return jdbcUrl;
+        }
     }
 
     @Override
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/StatementProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/StatementProxy.java
index 955fc81c05899967d9356587bc0e42dac97b0878..6a3d121a8a8431d05c0e0c5d8e7ba6adbbb741f6 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/StatementProxy.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/StatementProxy.java
@@ -94,37 +94,67 @@ public class StatementProxy<T extends Statement> extends AbstractStatementProxy<
 
     @Override
     public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
-        // TODO
-        return 0;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Integer, T>() {
+            @Override
+            public Integer execute(T statement, Object... args) throws SQLException {
+                return statement.executeUpdate((String) args[0],(int)args[1]);
+            }
+        }, sql,autoGeneratedKeys);
     }
 
     @Override
     public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
-        // TODO
-        return 0;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Integer, T>() {
+            @Override
+            public Integer execute(T statement, Object... args) throws SQLException {
+                return statement.executeUpdate((String) args[0],(int [])args[1]);
+            }
+        }, sql,columnIndexes);
     }
 
     @Override
     public int executeUpdate(String sql, String[] columnNames) throws SQLException {
-        // TODO
-        return 0;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Integer, T>() {
+            @Override
+            public Integer execute(T statement, Object... args) throws SQLException {
+                return statement.executeUpdate((String) args[0],(String[])args[1]);
+            }
+        }, sql,columnNames);
     }
 
     @Override
     public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
-        // TODO
-        return false;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Boolean, T>() {
+            @Override
+            public Boolean execute(T statement, Object... args) throws SQLException {
+                return statement.execute((String) args[0],(int)args[1]);
+            }
+        }, sql,autoGeneratedKeys);
     }
 
     @Override
     public boolean execute(String sql, int[] columnIndexes) throws SQLException {
-        // TODO
-        return false;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Boolean, T>() {
+            @Override
+            public Boolean execute(T statement, Object... args) throws SQLException {
+                return statement.execute((String) args[0],(int[])args[1]);
+            }
+        }, sql,columnIndexes);
     }
 
     @Override
     public boolean execute(String sql, String[] columnNames) throws SQLException {
-        // TODO
-        return false;
+        this.targetSQL = sql;
+        return ExecuteTemplate.execute(this, new StatementCallback<Boolean, T>() {
+            @Override
+            public Boolean execute(T statement, Object... args) throws SQLException {
+                return statement.execute((String) args[0],(String[])args[1]);
+            }
+        }, sql,columnNames);
     }
 }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/BaseTransactionalExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/BaseTransactionalExecutor.java
index 6114746ea62331f25ee171ee10e4f0c8010b8b5d..438abaea0e976e56fe7e8ddac729556db289da52 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/BaseTransactionalExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/BaseTransactionalExecutor.java
@@ -15,10 +15,6 @@
  */
 package io.seata.rm.datasource.exec;
 
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
 import io.seata.core.context.RootContext;
 import io.seata.rm.datasource.ConnectionProxy;
 import io.seata.rm.datasource.StatementProxy;
@@ -30,6 +26,11 @@ import io.seata.rm.datasource.sql.struct.TableMetaCache;
 import io.seata.rm.datasource.sql.struct.TableRecords;
 import io.seata.rm.datasource.undo.SQLUndoLog;
 
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.StringJoiner;
+
 /**
  * The type Base transactional executor.
  *
@@ -103,15 +104,12 @@ public abstract class BaseTransactionalExecutor<T, S extends Statement> implemen
      * @throws SQLException the sql exception
      */
     protected String buildWhereConditionByPKs(List<Field> pkRows) throws SQLException {
-        StringBuffer whereConditionAppender = new StringBuffer();
-        for (int i = 0; i < pkRows.size(); i++) {
-            Field field = pkRows.get(i);
-            whereConditionAppender.append(getColumnNameInSQL(field.getName()) + " = ?");
-            if (i < (pkRows.size() - 1)) {
-                whereConditionAppender.append(" OR ");
-            }
+        StringJoiner whereConditionAppender = new StringJoiner(" OR ");
+        for (Field field : pkRows) {
+            whereConditionAppender.add(getColumnNameInSQL(field.getName()) + " = ?");
         }
         return whereConditionAppender.toString();
+
     }
 
     /**
@@ -122,11 +120,7 @@ public abstract class BaseTransactionalExecutor<T, S extends Statement> implemen
      */
     protected String getColumnNameInSQL(String columnName) {
         String tableAlias = sqlRecognizer.getTableAlias();
-        if (tableAlias == null) {
-            return columnName;
-        } else {
-            return tableAlias + "." + columnName;
-        }
+        return tableAlias == null ? columnName : tableAlias + "." + columnName;
     }
 
     /**
@@ -137,11 +131,7 @@ public abstract class BaseTransactionalExecutor<T, S extends Statement> implemen
     protected String getFromTableInSQL() {
         String tableName = sqlRecognizer.getTableName();
         String tableAlias = sqlRecognizer.getTableAlias();
-        if (tableAlias == null) {
-            return tableName;
-        } else {
-            return tableName + " " + tableAlias;
-        }
+        return tableAlias == null ? tableName : tableName + " " + tableAlias;
     }
 
     /**
@@ -160,10 +150,9 @@ public abstract class BaseTransactionalExecutor<T, S extends Statement> implemen
      * @return the table meta
      */
     protected TableMeta getTableMeta(String tableName) {
-        if (tableMeta != null) {
-            return tableMeta;
+        if (tableMeta == null) {
+             tableMeta = TableMetaCache.getTableMeta(statementProxy.getConnectionProxy().getDataSourceProxy(), tableName);
         }
-        tableMeta = TableMetaCache.getTableMeta(statementProxy.getConnectionProxy().getDataSourceProxy(), tableName);
         return tableMeta;
     }
 
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java
index 26507eb74f349c13f00972747bbb97ada16a0014..c826911141f3c72b1be29dec457981fb7b47dc8e 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/DeleteExecutor.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringJoiner;
 
 import com.alibaba.druid.util.JdbcConstants;
 import io.seata.rm.datasource.ParametersHolder;
@@ -66,15 +67,12 @@ public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
         for (String column : tmeta.getAllColumns().keySet()) {
             columns.add(keywordChecker.checkAndReplace(column));
         }
-
         StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
-
-        for (int i = 0; i < columns.size(); i++) {
-            selectSQLAppender.append(getColumnNameInSQL(columns.get(i)));
-            if (i < (columns.size() - 1)) {
-                selectSQLAppender.append(", ");
-            }
+        StringJoiner columnSQL = new StringJoiner(", ");
+        for (String column:columns) {
+            columnSQL.add(getColumnNameInSQL(column));
         }
+        selectSQLAppender.append(columnSQL.toString());
         String whereCondition = null;
         ArrayList<Object> paramAppender = new ArrayList<>();
         if (statementProxy instanceof ParametersHolder) {
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/InsertExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/InsertExecutor.java
index 9668fe62332261c2f3f735048d1a78416dd1a99a..ac3130f3f1774702dfcb59a53df41be111faa326 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/InsertExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/InsertExecutor.java
@@ -25,6 +25,8 @@ import io.seata.rm.datasource.sql.struct.ColumnMeta;
 import io.seata.rm.datasource.sql.struct.Null;
 import io.seata.rm.datasource.sql.struct.TableMeta;
 import io.seata.rm.datasource.sql.struct.TableRecords;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -33,6 +35,7 @@ import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.StringJoiner;
 
 /**
  * The type Insert executor.
@@ -44,6 +47,7 @@ import java.util.Map;
  */
 public class InsertExecutor<T, S extends Statement> extends AbstractDMLBaseExecutor<T, S> {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(InsertExecutor.class);
     protected static final String ERR_SQL_STATE = "S1009";
 
     /**
@@ -134,6 +138,7 @@ public class InsertExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
             // specify Statement.RETURN_GENERATED_KEYS to
             // Statement.executeUpdate() or Connection.prepareStatement().
             if (ERR_SQL_STATE.equalsIgnoreCase(e.getSQLState())) {
+                LOGGER.warn("Fail to get auto-generated keys, use \'SELECT LAST_INSERT_ID()\' instead. Be cautious, statement could be polluted. Recommend you set the statement to return generated keys.");
                 genKeys = statementProxy.getTargetStatement().executeQuery("SELECT LAST_INSERT_ID()");
             } else {
                 throw e;
@@ -151,12 +156,12 @@ public class InsertExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
         TableRecords afterImage;
         String pk = getTableMeta().getPkName();
         StringBuffer selectSQLAppender = new StringBuffer("SELECT * FROM " + getTableMeta().getTableName() + " WHERE ");
-        for (int i = 1; i <= pkValues.size(); i++) {
-            selectSQLAppender.append(pk + "=?");
-            if (i < pkValues.size()) {
-                selectSQLAppender.append(" OR ");
-            }
+
+        StringJoiner pkValuesJoiner = new StringJoiner(" OR ");
+        for (Object pkValue:pkValues) {
+            pkValuesJoiner.add(pk + "=?");
         }
+        selectSQLAppender.append(pkValuesJoiner.toString());
         PreparedStatement ps = null;
         ResultSet rs = null;
         try {
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java
index 068ede397b09ff9cec056356e518c2fb6f5128a9..95f1122f47b05f7b2537eaf3ee617f74e4a58a57 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/exec/UpdateExecutor.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringJoiner;
 
 import io.seata.rm.datasource.ParametersHolder;
 import io.seata.rm.datasource.StatementProxy;
@@ -133,12 +134,11 @@ public class UpdateExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
             // PK should be included.
             selectSQLAppender.append(getColumnNameInSQL(tmeta.getPkName()) + ", ");
         }
-        for (int i = 0; i < updateColumns.size(); i++) {
-            selectSQLAppender.append(updateColumns.get(i));
-            if (i < (updateColumns.size() - 1)) {
-                selectSQLAppender.append(", ");
-            }
+        StringJoiner columnsSQL = new StringJoiner(", ");
+        for (String column:updateColumns) {
+            columnsSQL.add(column);
         }
+        selectSQLAppender.append(columnsSQL.toString());
         List<Field> pkRows = beforeImage.pkRows();
         selectSQLAppender.append(
             " FROM " + getFromTableInSQL() + " WHERE " + buildWhereConditionByPKs(pkRows));
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableMeta.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableMeta.java
index 116e013b7058947dce588c19ebf82ff4bc95df27..d0dfd8d98b4f320ef226eb6cc231e73caa9f1fa2 100755
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableMeta.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableMeta.java
@@ -22,6 +22,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import io.seata.common.exception.NotSupportYetException;
+import io.seata.common.util.CollectionUtils;
 
 /**
  * The type Table meta.
@@ -164,7 +165,11 @@ public class TableMeta {
             return false;
         }
 
-        return cols.containsAll(pk);
+        if (cols.containsAll(pk)) {
+            return true;
+        } else {
+            return CollectionUtils.toUpperList(cols).containsAll(CollectionUtils.toUpperList(pk));
+        }
     }
 
     /**
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java
index b78189f5535590b2e52a314cea8c0044a052ed98..4684f0ec83463c3a9ac67a365fdce20b8fd0c5f1 100755
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/struct/TableRecords.java
@@ -15,19 +15,21 @@
  */
 package io.seata.rm.datasource.sql.struct;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import io.seata.common.exception.ShouldNeverHappenException;
+
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 
-import io.seata.common.exception.ShouldNeverHappenException;
-
 /**
  * The type Table records.
  *
  * @author sharajava
  */
+@JsonIgnoreProperties({"tableMeta"})
 public class TableRecords {
 
     private transient TableMeta tableMeta;
@@ -155,27 +157,7 @@ public class TableRecords {
      * @return the table records
      */
     public static TableRecords empty(TableMeta tableMeta) {
-        return new TableRecords(tableMeta) {
-            @Override
-            public int size() {
-                return 0;
-            }
-
-            @Override
-            public List<Field> pkRows() {
-                return new ArrayList<>();
-            }
-
-            @Override
-            public void add(Row row) {
-                throw new UnsupportedOperationException("xxx");
-            }
-
-            @Override
-            public TableMeta getTableMeta() {
-                throw new UnsupportedOperationException("xxx");
-            }
-        };
+        return new EmptyTableRecords(tableMeta);
     }
 
     /**
@@ -198,7 +180,7 @@ public class TableRecords {
                 ColumnMeta col = tmeta.getColumnMeta(colName);
                 Field field = new Field();
                 field.setName(col.getColumnName());
-                if (tmeta.getPkName().equals(field.getName())) {
+                if (tmeta.getPkName().equalsIgnoreCase(field.getName())) {
                     field.setKeyType(KeyType.PrimaryKey);
                 }
                 field.setType(col.getDataType());
@@ -213,4 +195,33 @@ public class TableRecords {
         }
         return records;
     }
+
+    public static class EmptyTableRecords extends TableRecords {
+
+        public EmptyTableRecords() {}
+
+        public EmptyTableRecords(TableMeta tableMeta) {
+            this.setTableMeta(tableMeta);
+        }
+
+        @Override
+        public int size() {
+            return 0;
+        }
+
+        @Override
+        public List<Field> pkRows() {
+            return new ArrayList<>();
+        }
+
+        @Override
+        public void add(Row row) {
+            throw new UnsupportedOperationException("xxx");
+        }
+
+        @Override
+        public TableMeta getTableMeta() {
+            throw new UnsupportedOperationException("xxx");
+        }
+    }
 }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogConstants.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..1f561baf9ae8e5b70ec7af0088c3dbff8a2175f7
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogConstants.java
@@ -0,0 +1,30 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.rm.datasource.undo;
+
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+
+/**
+ * @author Geng Zhang
+ */
+public class UndoLogConstants {
+
+    public final static String SERIALIZER_KEY = "serializer";
+    
+    public static final String DEFAULT_SERIALIZER = ConfigurationFactory.getInstance()
+            .getConfig(ConfigurationKeys.TRANSACTION_UNDO_LOG_SERIALIZATION, "jackson");
+}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogManager.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogManager.java
index 3b308c3eec31451c73cf9a792864a45bf6218e39..78f5b69ae3c7c61a362847ede42a7afb8fb764c3 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogManager.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogManager.java
@@ -15,10 +15,22 @@
  */
 package io.seata.rm.datasource.undo;
 
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
 import com.alibaba.druid.util.JdbcConstants;
+
 import io.seata.common.Constants;
 import io.seata.common.exception.NotSupportYetException;
 import io.seata.common.util.BlobUtils;
+import io.seata.common.util.CollectionUtils;
 import io.seata.core.exception.TransactionException;
 import io.seata.rm.datasource.ConnectionContext;
 import io.seata.rm.datasource.ConnectionProxy;
@@ -28,20 +40,13 @@ import io.seata.rm.datasource.sql.struct.TableMetaCache;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.sql.Blob;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.SQLIntegrityConstraintViolationException;
-import java.util.Set;
-
 import static io.seata.core.exception.TransactionExceptionCode.BranchRollbackFailed_Retriable;
 
 /**
  * The type Undo log manager.
  *
  * @author sharajava
+ * @author Geng Zhang
  */
 public final class UndoLogManager {
 
@@ -71,15 +76,17 @@ public final class UndoLogManager {
 
     private static String UNDO_LOG_TABLE_NAME = "undo_log";
 
-    private static String INSERT_UNDO_LOG_SQL = "INSERT INTO " + UNDO_LOG_TABLE_NAME + "\n" +
-        "\t(branch_id, xid, rollback_info, log_status, log_created, log_modified)\n" +
-        "VALUES (?, ?, ?, ?, now(), now())";
+    private static String INSERT_UNDO_LOG_SQL = "INSERT INTO " + UNDO_LOG_TABLE_NAME +
+        " (branch_id, xid, context, rollback_info, log_status, log_created, log_modified)" +
+        " VALUES (?, ?, ?, ?, ?, now(), now())";
 
-    private static String DELETE_UNDO_LOG_SQL = "DELETE FROM " + UNDO_LOG_TABLE_NAME + "\n" +
-        "\tWHERE branch_id = ? AND xid = ?";
+    private static String DELETE_UNDO_LOG_SQL = "DELETE FROM " + UNDO_LOG_TABLE_NAME +
+        " WHERE branch_id = ? AND xid = ?";
 
-    private static String SELECT_UNDO_LOG_SQL = "SELECT * FROM " + UNDO_LOG_TABLE_NAME
-        + " WHERE  branch_id = ? AND xid = ? FOR UPDATE";
+    private static String SELECT_UNDO_LOG_SQL = "SELECT * FROM " + UNDO_LOG_TABLE_NAME +
+        " WHERE branch_id = ? AND xid = ? FOR UPDATE";
+
+    private static final ThreadLocal<String> SERIALIZER_LOCAL = new ThreadLocal<>();
 
     private UndoLogManager() {
 
@@ -103,13 +110,15 @@ public final class UndoLogManager {
         branchUndoLog.setBranchId(branchID);
         branchUndoLog.setSqlUndoLogs(connectionContext.getUndoItems());
 
-        byte[] undoLogContent = UndoLogParserFactory.getInstance().encode(branchUndoLog);
+        UndoLogParser parser = UndoLogParserFactory.getInstance();
+        byte[] undoLogContent = parser.encode(branchUndoLog);
 
         if (LOGGER.isDebugEnabled()) {
-            LOGGER.debug("Flushing UNDO LOG: {}",new String(undoLogContent, Constants.DEFAULT_CHARSET));
+            LOGGER.debug("Flushing UNDO LOG: {}", new String(undoLogContent, Constants.DEFAULT_CHARSET));
         }
 
-        insertUndoLogWithNormal(xid, branchID, undoLogContent, cp.getTargetConnection());
+        insertUndoLogWithNormal(xid, branchID, buildContext(parser.getName()), undoLogContent,
+            cp.getTargetConnection());
     }
 
     private static void assertDbSupport(String dbType) {
@@ -122,8 +131,8 @@ public final class UndoLogManager {
      * Undo.
      *
      * @param dataSourceProxy the data source proxy
-     * @param xid the xid
-     * @param branchId the branch id
+     * @param xid             the xid
+     * @param branchId        the branch id
      * @throws TransactionException the transaction exception
      */
     public static void undo(DataSourceProxy dataSourceProxy, String xid, long branchId) throws TransactionException {
@@ -157,22 +166,36 @@ public final class UndoLogManager {
                     if (!canUndo(state)) {
                         if (LOGGER.isInfoEnabled()) {
                             LOGGER.info("xid {} branch {}, ignore {} undo_log",
-                                    xid, branchId, state);
+                                xid, branchId, state);
                         }
                         return;
                     }
 
+                    String contextString = rs.getString("context");
+                    Map<String, String> context = parseContext(contextString);
                     Blob b = rs.getBlob("rollback_info");
                     byte[] rollbackInfo = BlobUtils.blob2Bytes(b);
-                    BranchUndoLog branchUndoLog = UndoLogParserFactory.getInstance().decode(rollbackInfo);
-
-                    for (SQLUndoLog sqlUndoLog : branchUndoLog.getSqlUndoLogs()) {
-                        TableMeta tableMeta = TableMetaCache.getTableMeta(dataSourceProxy, sqlUndoLog.getTableName());
-                        sqlUndoLog.setTableMeta(tableMeta);
-                        AbstractUndoExecutor undoExecutor = UndoExecutorFactory.getUndoExecutor(
-                            dataSourceProxy.getDbType(),
-                            sqlUndoLog);
-                        undoExecutor.executeOn(conn);
+
+                    String serializer = context == null ? null : context.get(UndoLogConstants.SERIALIZER_KEY);
+                    UndoLogParser parser = serializer == null ? UndoLogParserFactory.getInstance() :
+                        UndoLogParserFactory.getInstance(serializer);
+                    BranchUndoLog branchUndoLog = parser.decode(rollbackInfo);
+
+                    try {
+                        // put serializer name to local
+                        SERIALIZER_LOCAL.set(parser.getName());
+
+                        for (SQLUndoLog sqlUndoLog : branchUndoLog.getSqlUndoLogs()) {
+                            TableMeta tableMeta = TableMetaCache.getTableMeta(dataSourceProxy, sqlUndoLog.getTableName());
+                            sqlUndoLog.setTableMeta(tableMeta);
+                            AbstractUndoExecutor undoExecutor = UndoExecutorFactory.getUndoExecutor(
+                                    dataSourceProxy.getDbType(),
+                                    sqlUndoLog);
+                            undoExecutor.executeOn(conn);
+                        }
+                    } finally {
+                        // remove serializer name
+                        SERIALIZER_LOCAL.remove();
                     }
                 }
 
@@ -190,14 +213,14 @@ public final class UndoLogManager {
                     conn.commit();
                     if (LOGGER.isInfoEnabled()) {
                         LOGGER.info("xid {} branch {}, undo_log deleted with {}",
-                                xid, branchId, State.GlobalFinished.name());
+                            xid, branchId, State.GlobalFinished.name());
                     }
                 } else {
-                    insertUndoLogWithGlobalFinished(xid, branchId, conn);
+                    insertUndoLogWithGlobalFinished(xid, branchId, UndoLogParserFactory.getInstance(), conn);
                     conn.commit();
                     if (LOGGER.isInfoEnabled()) {
                         LOGGER.info("xid {} branch {}, undo_log added with {}",
-                                xid, branchId, State.GlobalFinished.name());
+                            xid, branchId, State.GlobalFinished.name());
                     }
                 }
 
@@ -206,7 +229,7 @@ public final class UndoLogManager {
                 // Possible undo_log has been inserted into the database by other processes, retrying rollback undo_log
                 if (LOGGER.isInfoEnabled()) {
                     LOGGER.info("xid {} branch {}, undo_log inserted, retry rollback",
-                            xid, branchId);
+                        xid, branchId);
                 }
             } catch (Throwable e) {
                 if (conn != null) {
@@ -266,7 +289,7 @@ public final class UndoLogManager {
             if (!(e instanceof SQLException)) {
                 e = new SQLException(e);
             }
-            throw (SQLException) e;
+            throw (SQLException)e;
         } finally {
             if (deletePST != null) {
                 deletePST.close();
@@ -278,8 +301,8 @@ public final class UndoLogManager {
     protected static String toBatchDeleteUndoLogSql(int xidSize, int branchIdSize) {
         StringBuilder sqlBuilder = new StringBuilder(64);
         sqlBuilder.append("DELETE FROM ")
-                .append(UNDO_LOG_TABLE_NAME)
-                .append(" WHERE  branch_id IN ");
+            .append(UNDO_LOG_TABLE_NAME)
+            .append(" WHERE  branch_id IN ");
         appendInParam(branchIdSize, sqlBuilder);
         sqlBuilder.append(" AND xid IN ");
         appendInParam(xidSize, sqlBuilder);
@@ -288,7 +311,7 @@ public final class UndoLogManager {
 
     protected static void appendInParam(int size, StringBuilder sqlBuilder) {
         sqlBuilder.append(" (");
-        for (int i = 0;i < size;i++) {
+        for (int i = 0; i < size; i++) {
             sqlBuilder.append("?");
             if (i < (size - 1)) {
                 sqlBuilder.append(",");
@@ -300,9 +323,9 @@ public final class UndoLogManager {
     /**
      * Delete undo log.
      *
-     * @param xid the xid
+     * @param xid      the xid
      * @param branchId the branch id
-     * @param conn the conn
+     * @param conn     the conn
      * @throws SQLException the sql exception
      */
     public static void deleteUndoLog(String xid, long branchId, Connection conn) throws SQLException {
@@ -316,7 +339,7 @@ public final class UndoLogManager {
             if (!(e instanceof SQLException)) {
                 e = new SQLException(e);
             }
-            throw (SQLException) e;
+            throw (SQLException)e;
         } finally {
             if (deletePST != null) {
                 deletePST.close();
@@ -324,31 +347,37 @@ public final class UndoLogManager {
         }
     }
 
-    private static void insertUndoLogWithNormal(String xid, long branchID,
-                                                byte[] undoLogContent, Connection conn) throws SQLException {
-        insertUndoLog(xid, branchID, undoLogContent, State.Normal, conn);
+    public static String getCurrentSerializer() {
+        return SERIALIZER_LOCAL.get();
     }
 
-    private static void insertUndoLogWithGlobalFinished(String xid, long branchID,
-                                                        Connection conn) throws SQLException {
-        insertUndoLog(xid, branchID, "{}".getBytes(Constants.DEFAULT_CHARSET), State.GlobalFinished, conn);
+    private static void insertUndoLogWithNormal(String xid, long branchID, String rollbackCtx,
+        byte[] undoLogContent, Connection conn) throws SQLException {
+        insertUndoLog(xid, branchID, rollbackCtx, undoLogContent, State.Normal, conn);
     }
 
-    private static void insertUndoLog(String xid, long branchID,
-                                      byte[] undoLogContent, State state, Connection conn) throws SQLException {
+    private static void insertUndoLogWithGlobalFinished(String xid, long branchID, UndoLogParser parser,
+        Connection conn) throws SQLException {
+        insertUndoLog(xid, branchID, buildContext(parser.getName()),
+            parser.getDefaultContent(), State.GlobalFinished, conn);
+    }
+
+    private static void insertUndoLog(String xid, long branchID, String rollbackCtx,
+        byte[] undoLogContent, State state, Connection conn) throws SQLException {
         PreparedStatement pst = null;
         try {
             pst = conn.prepareStatement(INSERT_UNDO_LOG_SQL);
             pst.setLong(1, branchID);
             pst.setString(2, xid);
-            pst.setBlob(3, BlobUtils.bytes2Blob(undoLogContent));
-            pst.setInt(4, state.getValue());
+            pst.setString(3, rollbackCtx);
+            pst.setBlob(4, BlobUtils.bytes2Blob(undoLogContent));
+            pst.setInt(5, state.getValue());
             pst.executeUpdate();
         } catch (Exception e) {
             if (!(e instanceof SQLException)) {
                 e = new SQLException(e);
             }
-            throw (SQLException) e;
+            throw (SQLException)e;
         } finally {
             if (pst != null) {
                 pst.close();
@@ -359,4 +388,15 @@ public final class UndoLogManager {
     private static boolean canUndo(int state) {
         return state == State.Normal.getValue();
     }
+
+    private static String buildContext(String serializer) {
+        Map<String, String> map = new HashMap<>();
+        map.put(UndoLogConstants.SERIALIZER_KEY, serializer);
+        return CollectionUtils.encodeMap(map);
+    }
+
+    private static Map<String, String> parseContext(String data) {
+        return CollectionUtils.decodeMap(data);
+    }
+
 }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParser.java
index 5dc8a1a1e39bd1e11c3ed1964fd100bcd55b947c..6728b30a372157ab04680032115147a9ca94356d 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParser.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParser.java
@@ -23,6 +23,20 @@ package io.seata.rm.datasource.undo;
  */
 public interface UndoLogParser {
 
+    /**
+     * Get the name of parser;
+     * 
+     * @return the name of parser
+     */
+    String getName();
+
+    /**
+     * Get default context of this parser
+     * 
+     * @return the default content if undo log is empty
+     */
+    byte[] getDefaultContent();
+
     /**
      * Encode branch undo log to byte array.
      *
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParserFactory.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParserFactory.java
index 7bfa1763359f0a0aecb0ceba03107f2eff7c213d..66a263c022091d9fea3c0f9330efe53f46dda071 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParserFactory.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/UndoLogParserFactory.java
@@ -16,8 +16,9 @@
 package io.seata.rm.datasource.undo;
 
 import io.seata.common.loader.EnhancedServiceLoader;
-import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 /**
  * The type Undo log parser factory.
@@ -27,14 +28,17 @@ import io.seata.core.constants.ConfigurationKeys;
  */
 public class UndoLogParserFactory {
 
+    /**
+     * {serializerName:UndoLogParser}
+     */
+    private static final ConcurrentMap<String, UndoLogParser> INSTANCES = new ConcurrentHashMap<>();
+
     private static class SingletonHolder {
-        private static final UndoLogParser INSTANCE = 
-                EnhancedServiceLoader.load(UndoLogParser.class, ConfigurationFactory.getInstance()
-                        .getConfig(ConfigurationKeys.TRANSACTION_UNDO_LOG_SERIALIZATION, "fastjson"));
+        private static final UndoLogParser INSTANCE = getInstance(UndoLogConstants.DEFAULT_SERIALIZER);
     }
 
     /**
-     * Gets instance.
+     * Gets default UndoLogParser instance.
      *
      * @return the instance
      */
@@ -42,4 +46,23 @@ public class UndoLogParserFactory {
         return SingletonHolder.INSTANCE;
     }
 
+    /**
+     * Gets UndoLogParser by name
+     *
+     * @param name parser name
+     * @return the UndoLogParser
+     */
+    public static UndoLogParser getInstance(String name) {
+        UndoLogParser parser = INSTANCES.get(name);
+        if (parser == null) {
+            synchronized (UndoLogParserFactory.class) {
+                parser = INSTANCES.get(name);
+                if (parser == null) {
+                    parser = EnhancedServiceLoader.load(UndoLogParser.class, name);
+                    INSTANCES.putIfAbsent(name, parser);
+                }
+            }
+        }
+        return parser;
+    }
 }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParser.java
similarity index 71%
rename from rm-datasource/src/main/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParser.java
rename to rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParser.java
index bab16534b821393d28ca1f3536c0a5ca999724e4..32bc74597287b148ae59ac9fe158c9052a933cfc 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParser.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParser.java
@@ -13,20 +13,35 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.rm.datasource.undo;
+package io.seata.rm.datasource.undo.parser;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import io.seata.common.Constants;
 import io.seata.common.loader.LoadLevel;
+import io.seata.rm.datasource.undo.BranchUndoLog;
+import io.seata.rm.datasource.undo.UndoLogParser;
 
 /**
  * The type Json based undo log parser.
  *
  * @author sharajava
  */
-@LoadLevel(name = "fastjson")
-public class JSONBasedUndoLogParser implements UndoLogParser {
+@Deprecated
+@LoadLevel(name = FastjsonUndoLogParser.NAME)
+public class FastjsonUndoLogParser implements UndoLogParser {
+
+    public static final String NAME = "fastjson";
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public byte[] getDefaultContent() {
+        return "{}".getBytes(Constants.DEFAULT_CHARSET);
+    }
 
     @Override
     public byte[] encode(BranchUndoLog branchUndoLog) {
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..3baee85f2a2e3caa79ea857f9e35b65610348c9b
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParser.java
@@ -0,0 +1,81 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.rm.datasource.undo.parser;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.seata.common.Constants;
+import io.seata.common.loader.LoadLevel;
+import io.seata.rm.datasource.undo.BranchUndoLog;
+import io.seata.rm.datasource.undo.UndoLogParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * The type Json based undo log parser.
+ *
+ * @author jsbxyyx
+ */
+@LoadLevel(name = JacksonUndoLogParser.NAME)
+public class JacksonUndoLogParser implements UndoLogParser {
+
+    public static final String NAME = "jackson";
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUndoLogParser.class);
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    static {
+        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        MAPPER.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
+    }
+
+    @Override
+    public String getName() {
+        return NAME;
+    }
+
+    @Override
+    public byte[] getDefaultContent() {
+        return "{}".getBytes(Constants.DEFAULT_CHARSET);
+    }
+
+    @Override
+    public byte[] encode(BranchUndoLog branchUndoLog) {
+        try {
+            byte[] bytes = MAPPER.writeValueAsBytes(branchUndoLog);
+            return bytes;
+        } catch (JsonProcessingException e) {
+            LOGGER.error("json encode exception, {}", e.getMessage(), e);
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public BranchUndoLog decode(byte[] bytes) {
+        try {
+            BranchUndoLog branchUndoLog = MAPPER.readValue(bytes, BranchUndoLog.class);
+            return branchUndoLog;
+        } catch (IOException e) {
+            LOGGER.error("json decode exception, {}", e.getMessage(), e);
+            throw new RuntimeException(e);
+        }
+    }
+
+}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff2dac29a6567eff4f25c0caa67474025484147d
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParser.java
@@ -0,0 +1,219 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.rm.datasource.undo.parser;
+
+import io.protostuff.Input;
+import io.protostuff.LinkedBuffer;
+import io.protostuff.Output;
+import io.protostuff.Pipe;
+import io.protostuff.ProtostuffIOUtil;
+import io.protostuff.Schema;
+import io.protostuff.WireFormat.FieldType;
+import io.protostuff.runtime.DefaultIdStrategy;
+import io.protostuff.runtime.Delegate;
+import io.protostuff.runtime.RuntimeEnv;
+import io.protostuff.runtime.RuntimeSchema;
+import io.seata.common.loader.LoadLevel;
+import io.seata.rm.datasource.undo.BranchUndoLog;
+import io.seata.rm.datasource.undo.UndoLogParser;
+
+import java.io.IOException;
+
+/**
+ * The type protostuff based undo log parser.
+ *
+ * @author Geng Zhang
+ */
+@LoadLevel(name = ProtostuffUndoLogParser.NAME)
+public class ProtostuffUndoLogParser implements UndoLogParser {
+
+    public static final String NAME = "protostuff";
+    
+    private final static DefaultIdStrategy ID_STRATEGY = ((DefaultIdStrategy) RuntimeEnv.ID_STRATEGY);
+
+    static {
+        ID_STRATEGY.registerDelegate(new DateDelegate());
+        ID_STRATEGY.registerDelegate(new TimestampDelegate());
+        ID_STRATEGY.registerDelegate(new SqlDateDelegate());
+        ID_STRATEGY.registerDelegate(new TimeDelegate());
+    }
+
+    private static final Schema<BranchUndoLog> SCHEMA = RuntimeSchema.getSchema(BranchUndoLog.class);
+
+    @Override
+    public String getName() {
+        return ProtostuffUndoLogParser.NAME;
+    }
+
+    @Override
+    public byte[] getDefaultContent() {
+        return new byte[0];
+    }
+
+    @Override
+    public byte[] encode(BranchUndoLog branchUndoLog) {
+        // Re-use (manage) this buffer to avoid allocating on every serialization
+        LinkedBuffer buffer = LinkedBuffer.allocate(512);
+        // ser
+        try {
+            return ProtostuffIOUtil.toByteArray(branchUndoLog, SCHEMA, buffer);
+        } finally {
+            buffer.clear();
+        }
+    }
+
+    @Override
+    public BranchUndoLog decode(byte[] bytes) {
+        if (bytes.length == 0) {
+            return new BranchUndoLog();
+        }
+        BranchUndoLog fooParsed = SCHEMA.newMessage();
+        ProtostuffIOUtil.mergeFrom(bytes, fooParsed, SCHEMA);
+        return fooParsed;
+    }
+
+    /**
+     * Delegate for java.sql.Timestamp
+     * 
+     * @author zhangsen
+     */
+    public static class TimestampDelegate implements Delegate<java.sql.Timestamp> {
+
+        @Override
+        public FieldType getFieldType() {
+            return FieldType.FIXED64;
+        }
+
+        @Override
+        public Class<?> typeClass() {
+            return java.sql.Timestamp.class;
+        }
+
+        @Override
+        public java.sql.Timestamp readFrom(Input input) throws IOException {
+            return new java.sql.Timestamp(input.readFixed64());
+        }
+
+        @Override
+        public void writeTo(Output output, int number, java.sql.Timestamp value, boolean repeated) throws IOException {
+            output.writeFixed64(number, value.getTime(), repeated);
+        }
+
+        @Override
+        public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
+            output.writeFixed64(number, input.readFixed64(), repeated);
+        }
+    }
+
+    /**
+     * Delegate for java.sql.Date
+     *
+     * @author zhangsen
+     */
+    public static class SqlDateDelegate implements Delegate<java.sql.Date> {
+
+        @Override
+        public FieldType getFieldType() {
+            return FieldType.FIXED64;
+        }
+
+        @Override
+        public Class<?> typeClass() {
+            return java.sql.Date.class;
+        }
+
+        @Override
+        public java.sql.Date readFrom(Input input) throws IOException {
+            return new java.sql.Date(input.readFixed64());
+        }
+
+        @Override
+        public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
+            output.writeFixed64(number, input.readFixed64(), repeated);
+        }
+
+        @Override
+        public void writeTo(Output output, int number, java.sql.Date value, boolean repeated) throws IOException {
+            output.writeFixed64(number, value.getTime(), repeated);
+        }
+    }
+
+    /**
+     * Delegate for java.sql.Time
+     *
+     * @author zhangsen
+     */
+    public static class TimeDelegate implements Delegate<java.sql.Time> {
+
+        @Override
+        public FieldType getFieldType() {
+            return FieldType.FIXED64;
+        }
+
+        @Override
+        public Class<?> typeClass() {
+            return java.sql.Time.class;
+        }
+
+        @Override
+        public java.sql.Time readFrom(Input input) throws IOException {
+            return new java.sql.Time(input.readFixed64());
+        }
+
+        @Override
+        public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
+            output.writeFixed64(number, input.readFixed64(), repeated);
+        }
+
+        @Override
+        public void writeTo(Output output, int number, java.sql.Time value, boolean repeated) throws IOException {
+            output.writeFixed64(number, value.getTime(), repeated);
+        }
+    }
+
+    /**
+     * Delegate for java.util.Date
+     *
+     * @author zhangsen
+     */
+    public static class DateDelegate implements Delegate<java.util.Date> {
+
+        @Override
+        public FieldType getFieldType() {
+            return FieldType.FIXED64;
+        }
+
+        @Override
+        public Class<?> typeClass() {
+            return java.util.Date.class;
+        }
+
+        @Override
+        public java.util.Date readFrom(Input input) throws IOException {
+            return new java.util.Date(input.readFixed64());
+        }
+
+        @Override
+        public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
+            output.writeFixed64(number, input.readFixed64(), repeated);
+        }
+
+        @Override
+        public void writeTo(Output output, int number, java.util.Date value, boolean repeated) throws IOException {
+            output.writeFixed64(number, value.getTime(), repeated);
+        }
+    }
+}
diff --git a/rm-datasource/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.UndoLogParser b/rm-datasource/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.UndoLogParser
index d521a0c7b940109ce2992444e0e257d668282b99..01276f709463665d9846fc7c335006666887ec3a 100644
--- a/rm-datasource/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.UndoLogParser
+++ b/rm-datasource/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.UndoLogParser
@@ -1 +1,3 @@
-io.seata.rm.datasource.undo.JSONBasedUndoLogParser
\ No newline at end of file
+io.seata.rm.datasource.undo.parser.FastjsonUndoLogParser
+io.seata.rm.datasource.undo.parser.JacksonUndoLogParser
+io.seata.rm.datasource.undo.parser.ProtostuffUndoLogParser
\ No newline at end of file
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/exec/InsertExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/exec/InsertExecutorTest.java
index beb7c5ca793ac5e1dc6f040fb450def21c4278f6..0aacce0edd6e127fe32870a8f8917e8dcb7177d9 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/exec/InsertExecutorTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/exec/InsertExecutorTest.java
@@ -218,6 +218,23 @@ public class InsertExecutorTest {
         });
     }
 
+    @Test
+    public void testGetPkValuesByAuto_SQLException_WarnLog() throws SQLException {
+        doReturn(tableMeta).when(insertExecutor).getTableMeta();
+        ColumnMeta columnMeta = mock(ColumnMeta.class);
+        Map<String, ColumnMeta> columnMetaMap = new HashMap<>();
+        columnMetaMap.put(ID_COLUMN, columnMeta);
+        when(columnMeta.isAutoincrement()).thenReturn(true);
+        when(tableMeta.getPrimaryKeyMap()).thenReturn(columnMetaMap);
+        PreparedStatement preparedStatement = mock(PreparedStatement.class);
+        when(statementProxy.getTargetStatement()).thenReturn(preparedStatement);
+        SQLException e = new SQLException("test warn log", InsertExecutor.ERR_SQL_STATE, 1);
+        when(preparedStatement.getGeneratedKeys()).thenThrow(e);
+        ResultSet genKeys = mock(ResultSet.class);
+        when(statementProxy.getTargetStatement().executeQuery("SELECT LAST_INSERT_ID()")).thenReturn(genKeys);
+        Assertions.assertTrue(insertExecutor.getPkValuesByAuto().isEmpty());
+    }
+
     @Test
     public void testGetPkValuesByAuto_GeneratedKeys_NoResult() throws SQLException {
         doReturn(tableMeta).when(insertExecutor).getTableMeta();
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseH2Test.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseH2Test.java
index 0fc5357527851c101628f1760269858996d6332e..924ed7b816ce90121e8d6153a1ff62b51c2f2a66 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseH2Test.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseH2Test.java
@@ -33,6 +33,7 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 
+
 /**
  * @author Geng Zhang
  */
@@ -75,7 +76,7 @@ public abstract class BaseH2Test {
 
     @BeforeEach
     private void prepareTable() {
-        execSQL("DROP TABLE table_name");
+        execSQL("DROP TABLE IF EXISTS table_name");
         execSQL("CREATE TABLE table_name ( `id` int(8), `name` varchar(64), PRIMARY KEY (`id`))");
     }
 
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseUndoLogParserTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseUndoLogParserTest.java
index b24c79ef722b699c01c99afcceb396c53e0b01ab..6ae70e0c01be6c170a09e58d4ee4a10a9a94fc0d 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseUndoLogParserTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/BaseUndoLogParserTest.java
@@ -32,7 +32,7 @@ import java.util.List;
  */
 public abstract class BaseUndoLogParserTest extends BaseH2Test{
 
-    private static final Logger LOGGER = LoggerFactory.getLogger(BaseUndoLogParserTest.class);
+    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
     
     public abstract UndoLogParser getParser();
     
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserFactoryTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserFactoryTest.java
index 04fbde6fdd1c61ccf528c85e16c8d18c213eb0e0..6a1c099957d7acfe62b8a65ea0400641fd4cfd22 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserFactoryTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserFactoryTest.java
@@ -15,6 +15,7 @@
  */
 package io.seata.rm.datasource.undo;
 
+import io.seata.rm.datasource.undo.parser.JacksonUndoLogParser;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -25,6 +26,6 @@ class UndoLogParserFactoryTest {
 
     @Test
     void getInstance() {
-        Assertions.assertTrue(UndoLogParserFactory.getInstance() instanceof JSONBasedUndoLogParser);
+        Assertions.assertTrue(UndoLogParserFactory.getInstance() instanceof JacksonUndoLogParser);
     }
 }
\ No newline at end of file
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserProviderTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserProviderTest.java
index 1d1d626d53c456fb56785c3db938e12a7c87b4f4..de4fb1f7539c3b0506795d1b2d09fdd8ef266bdc 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserProviderTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogParserProviderTest.java
@@ -17,6 +17,9 @@ package io.seata.rm.datasource.undo;
 
 import io.seata.common.loader.EnhancedServiceLoader;
 import io.seata.common.loader.EnhancedServiceNotFoundException;
+import io.seata.rm.datasource.undo.parser.FastjsonUndoLogParser;
+import io.seata.rm.datasource.undo.parser.JacksonUndoLogParser;
+import io.seata.rm.datasource.undo.parser.ProtostuffUndoLogParser;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -26,10 +29,18 @@ import org.junit.jupiter.api.Test;
 class UndoLogParserProviderTest {
 
     @Test
-    void testError(){
+    void testLoad(){
         UndoLogParser parser = EnhancedServiceLoader.load(UndoLogParser.class, "fastjson");
         Assertions.assertNotNull(parser);
-        Assertions.assertTrue(parser instanceof JSONBasedUndoLogParser);
+        Assertions.assertTrue(parser instanceof FastjsonUndoLogParser);
+        
+        parser = EnhancedServiceLoader.load(UndoLogParser.class, "jackson");
+        Assertions.assertNotNull(parser);
+        Assertions.assertTrue(parser instanceof JacksonUndoLogParser);
+
+        parser = EnhancedServiceLoader.load(UndoLogParser.class, "protostuff");
+        Assertions.assertNotNull(parser);
+        Assertions.assertTrue(parser instanceof ProtostuffUndoLogParser);
         
         try {
             EnhancedServiceLoader.load(UndoLogParser.class, "adadad");
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParserTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..dae15bcfefd01fb74adc5cd1cd26683e9625990b
--- /dev/null
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/FastjsonUndoLogParserTest.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.rm.datasource.undo.parser;
+
+import io.seata.rm.datasource.undo.BaseUndoLogParserTest;
+import io.seata.rm.datasource.undo.UndoLogParser;
+
+/**
+ * @author Geng Zhang
+ */
+public class FastjsonUndoLogParserTest extends BaseUndoLogParserTest {
+
+    FastjsonUndoLogParser parser = new FastjsonUndoLogParser();
+
+    @Override
+    public UndoLogParser getParser() {
+        return parser;
+    }
+}
\ No newline at end of file
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParserTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParserTest.java
similarity index 71%
rename from rm-datasource/src/test/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParserTest.java
rename to rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParserTest.java
index 41c96aabc5539e8a2b2a70fce4c7f9f1a3b27e94..dab9b08653069693fdfe719864e49f878d5ae94f 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/JSONBasedUndoLogParserTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/JacksonUndoLogParserTest.java
@@ -13,14 +13,17 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package io.seata.rm.datasource.undo;
+package io.seata.rm.datasource.undo.parser;
+
+import io.seata.rm.datasource.undo.BaseUndoLogParserTest;
+import io.seata.rm.datasource.undo.UndoLogParser;
 
 /**
  * @author Geng Zhang
  */
-public class JSONBasedUndoLogParserTest extends BaseUndoLogParserTest {
+public class JacksonUndoLogParserTest extends BaseUndoLogParserTest {
 
-    JSONBasedUndoLogParser parser = new JSONBasedUndoLogParser();
+    JacksonUndoLogParser parser = new JacksonUndoLogParser();
 
     @Override
     public UndoLogParser getParser() {
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParserTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f18c4e4eb3f8718bddebd4675027572b778c700
--- /dev/null
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/parser/ProtostuffUndoLogParserTest.java
@@ -0,0 +1,32 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.rm.datasource.undo.parser;
+
+import io.seata.rm.datasource.undo.BaseUndoLogParserTest;
+import io.seata.rm.datasource.undo.UndoLogParser;
+
+/**
+ * @author Geng Zhang
+ */
+class ProtostuffUndoLogParserTest extends BaseUndoLogParserTest {
+
+    ProtostuffUndoLogParser parser = new ProtostuffUndoLogParser();
+
+    @Override
+    public UndoLogParser getParser() {
+        return parser;
+    }
+}
\ No newline at end of file
diff --git a/server/pom.xml b/server/pom.xml
index 6e0aff5174715631c3603241db7cb100e0c78ca5..ed9b9249d26012f952fc84c704755e20e4758c62 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -44,6 +44,17 @@
             <artifactId>seata-discovery-all</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-codec-all</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-metrics-all</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <!-- for database -->
         <dependency>
@@ -62,6 +73,10 @@
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.beust</groupId>
+            <artifactId>jcommander</artifactId>
+        </dependency>
 
     </dependencies>
 
diff --git a/server/src/main/java/io/seata/server/ParameterParser.java b/server/src/main/java/io/seata/server/ParameterParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..5cb975ae707803fe4f1a42fc7c00b35964b48e55
--- /dev/null
+++ b/server/src/main/java/io/seata/server/ParameterParser.java
@@ -0,0 +1,116 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+
+/**
+ * The type parameter parser
+ *
+ * @author xingfudeshi@gmail.com
+ * @date 2019/05/30
+ */
+public class ParameterParser {
+    private static final String PROGRAM_NAME = "sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows)";
+    private static final int SERVER_DEFAULT_PORT = 8091;
+    private static final String SERVER_DEFAULT_BIND_IP = "0.0.0.0";
+    private static final String SERVER_DEFAULT_STORE_MODE = "file";
+
+
+    @Parameter(names = "--help", help = true)
+    private boolean help;
+    @Parameter(names = {"--host", "-h"}, description = "The host to bind.", order = 1)
+    private String host = SERVER_DEFAULT_BIND_IP;
+    @Parameter(names = {"--port", "-p"}, description = "The port to listen.", order = 2)
+    private int port = SERVER_DEFAULT_PORT;
+    @Parameter(names = {"--storeMode", "-m"}, description = "log store mode : file、db", order = 3)
+    private String storeMode = SERVER_DEFAULT_STORE_MODE;
+
+
+    public ParameterParser(String[] args) {
+        this.init(args);
+    }
+
+    /**
+     * initialize the parameter parser
+     *
+     * @param args
+     */
+    private void init(String[] args) {
+        try {
+            JCommander jCommander = JCommander.newBuilder().addObject(this).build();
+            jCommander.parse(args);
+            if (help) {
+                jCommander.setProgramName(PROGRAM_NAME);
+                jCommander.usage();
+                System.exit(0);
+            }
+        } catch (ParameterException e) {
+            printError(e);
+        }
+
+    }
+
+    /**
+     * print the error
+     *
+     * @param e
+     */
+    private void printError(ParameterException e) {
+        System.err.println("Option error " + e.getMessage());
+        e.getJCommander().setProgramName(PROGRAM_NAME);
+        e.usage();
+        System.exit(0);
+    }
+
+    /**
+     * Gets host
+     *
+     * @return host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Gets port
+     *
+     * @return port
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Gets store mode
+     *
+     * @return storeMode
+     */
+    public String getStoreMode() {
+        return storeMode;
+    }
+
+    /**
+     * is help
+     *
+     * @return help
+     */
+    public boolean isHelp() {
+        return help;
+    }
+}
diff --git a/server/src/main/java/io/seata/server/Server.java b/server/src/main/java/io/seata/server/Server.java
index 0cec9d18b8713a6c006597b82ec0cd5db1c653b5..bcc6460c435cc410b690b5664b72c22491be75f3 100644
--- a/server/src/main/java/io/seata/server/Server.java
+++ b/server/src/main/java/io/seata/server/Server.java
@@ -15,19 +15,20 @@
  */
 package io.seata.server;
 
-import java.io.IOException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
 import io.seata.common.XID;
 import io.seata.common.thread.NamedThreadFactory;
 import io.seata.common.util.NetUtil;
 import io.seata.core.rpc.netty.RpcServer;
 import io.seata.core.rpc.netty.ShutdownHook;
 import io.seata.server.coordinator.DefaultCoordinator;
+import io.seata.server.metrics.MetricsManager;
 import io.seata.server.session.SessionHolder;
 
+import java.io.IOException;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
 /**
  * The type Server.
  *
@@ -39,7 +40,6 @@ public class Server {
     private static final int MAX_SERVER_POOL_SIZE = 500;
     private static final int MAX_TASK_QUEUE_SIZE = 20000;
     private static final int KEEP_ALIVE_TIME = 500;
-    private static final int SERVER_DEFAULT_PORT = 8091;
     private static final ThreadPoolExecutor WORKING_THREADS = new ThreadPoolExecutor(MIN_SERVER_POOL_SIZE,
         MAX_SERVER_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
         new LinkedBlockingQueue<>(MAX_TASK_QUEUE_SIZE),
@@ -52,28 +52,20 @@ public class Server {
      * @throws IOException the io exception
      */
     public static void main(String[] args) throws IOException {
-        RpcServer rpcServer = new RpcServer(WORKING_THREADS);
+        //initialize the metrics
+        MetricsManager.get().init();
 
-        int port = SERVER_DEFAULT_PORT;
-        //server port
-        if (args.length > 0) {
-            try {
-                port = Integer.parseInt(args[0]);
-            } catch (NumberFormatException e) {
-                System.err.println("Usage: sh services-server.sh $LISTEN_PORT $PATH_FOR_PERSISTENT_DATA");
-                System.exit(0);
-            }
-        }
-        rpcServer.setListenPort(port);
-
-        //log store mode : file、db
-        String storeMode = null;
-        if (args.length > 1) {
-            storeMode = args[1];
-        }
+        //initialize the parameter parser
+        ParameterParser parameterParser = new ParameterParser(args);
 
+        RpcServer rpcServer = new RpcServer(WORKING_THREADS);
+        //server host
+        rpcServer.setHost(parameterParser.getHost());
+        //server port
+        rpcServer.setListenPort(parameterParser.getPort());
         UUIDGenerator.init(1);
-        SessionHolder.init(storeMode);
+        //log store mode : file、db
+        SessionHolder.init(parameterParser.getStoreMode());
 
         DefaultCoordinator coordinator = new DefaultCoordinator(rpcServer);
         coordinator.init();
@@ -81,8 +73,9 @@ public class Server {
         // register ShutdownHook
         ShutdownHook.getInstance().addDisposable(coordinator);
 
-        if (args.length > 2) {
-            XID.setIpAddress(args[2]);
+        //127.0.0.1 and 0.0.0.0 are not valid here.
+        if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
+            XID.setIpAddress(parameterParser.getHost());
         } else {
             XID.setIpAddress(NetUtil.getLocalIp());
         }
diff --git a/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java b/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
index 0408a3bc6146554a2fb724dd067a16bcf0066d6f..418132d7652a3fe0b21c2180abef305fba5d59c6 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
@@ -27,6 +27,7 @@ import io.seata.common.util.CollectionUtils;
 import io.seata.common.util.DurationUtil;
 import io.seata.config.ConfigurationFactory;
 import io.seata.core.constants.ConfigurationKeys;
+import io.seata.core.event.EventBus;
 import io.seata.core.exception.TransactionException;
 import io.seata.core.model.BranchStatus;
 import io.seata.core.model.BranchType;
@@ -60,6 +61,8 @@ import io.seata.core.rpc.ServerMessageSender;
 import io.seata.core.rpc.TransactionMessageHandler;
 import io.seata.core.rpc.netty.RpcServer;
 import io.seata.server.AbstractTCInboundHandler;
+import io.seata.server.event.EventBusManager;
+import io.seata.core.event.GlobalTransactionEvent;
 import io.seata.server.session.BranchSession;
 import io.seata.server.session.GlobalSession;
 import io.seata.server.session.SessionHolder;
@@ -125,6 +128,8 @@ public class DefaultCoordinator extends AbstractTCInboundHandler
 
     private Core core = CoreFactory.get();
 
+    private EventBus eventBus = EventBusManager.get();
+
     /**
      * Instantiates a new Default coordinator.
      *
@@ -265,6 +270,13 @@ public class DefaultCoordinator extends AbstractTCInboundHandler
                 globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
                 globalSession.close();
                 globalSession.changeStatus(GlobalStatus.TimeoutRollbacking);
+
+                //transaction timeout and start rollbacking event
+                eventBus.post(
+                    new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+                        globalSession.getTransactionName(), globalSession.getBeginTime(), null,
+                        globalSession.getStatus()));
+
                 return true;
             });
             if (!shouldTimeout) {
diff --git a/server/src/main/java/io/seata/server/coordinator/DefaultCore.java b/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
index 493d7a4e995515cb8d2a471a886fab0a36c0af19..12adb44d9dcff9a6b7241742d798e1d55c44750d 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
@@ -15,13 +15,15 @@
  */
 package io.seata.server.coordinator;
 
-import io.seata.common.XID;
+import io.seata.core.event.EventBus;
 import io.seata.core.exception.TransactionException;
 import io.seata.core.exception.TransactionExceptionCode;
 import io.seata.core.model.BranchStatus;
 import io.seata.core.model.BranchType;
 import io.seata.core.model.GlobalStatus;
 import io.seata.core.model.ResourceManagerInbound;
+import io.seata.server.event.EventBusManager;
+import io.seata.core.event.GlobalTransactionEvent;
 import io.seata.server.lock.LockManager;
 import io.seata.server.lock.LockerFactory;
 import io.seata.server.session.BranchSession;
@@ -50,6 +52,8 @@ public class DefaultCore implements Core {
 
     private ResourceManagerInbound resourceManagerInbound;
 
+    private EventBus eventBus = EventBusManager.get();
+
     @Override
     public void setResourceManagerInbound(ResourceManagerInbound resourceManagerInbound) {
         this.resourceManagerInbound = resourceManagerInbound;
@@ -77,6 +81,7 @@ public class DefaultCore implements Core {
             try {
                 globalSession.addBranch(branchSession);
             } catch (RuntimeException ex) {
+                branchSession.unlock();
                 throw new TransactionException(FailedToAddBranch);
             }
             return branchSession.getBranchId();
@@ -123,6 +128,10 @@ public class DefaultCore implements Core {
 
         session.begin();
 
+        //transaction start event
+        eventBus.post(new GlobalTransactionEvent(session.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+            session.getTransactionName(), session.getBeginTime(), null, session.getStatus()));
+
         return session.getXid();
     }
 
@@ -158,6 +167,10 @@ public class DefaultCore implements Core {
 
     @Override
     public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
+        //start committing event
+        eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+            globalSession.getTransactionName(), globalSession.getBeginTime(), null, globalSession.getStatus()));
+
         for (BranchSession branchSession : globalSession.getSortedBranches()) {
             BranchStatus currentStatus = branchSession.getStatus();
             if (currentStatus == BranchStatus.PhaseOne_Failed) {
@@ -215,7 +228,14 @@ public class DefaultCore implements Core {
             return;
         }
         SessionHelper.endCommitted(globalSession);
+
+        //committed event
+        eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+            globalSession.getTransactionName(), globalSession.getBeginTime(), System.currentTimeMillis(),
+            globalSession.getStatus()));
+
         LOGGER.info("Global[{}] committing is successfully done.", globalSession.getXid());
+
     }
 
     private void asyncCommit(GlobalSession globalSession) throws TransactionException {
@@ -267,6 +287,10 @@ public class DefaultCore implements Core {
 
     @Override
     public void doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
+        //start rollback event
+        eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+            globalSession.getTransactionName(), globalSession.getBeginTime(), null, globalSession.getStatus()));
+
         for (BranchSession branchSession : globalSession.getReverseSortedBranches()) {
             BranchStatus currentBranchStatus = branchSession.getStatus();
             if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
@@ -281,7 +305,7 @@ public class DefaultCore implements Core {
                 switch (branchStatus) {
                     case PhaseTwo_Rollbacked:
                         globalSession.removeBranch(branchSession);
-                        LOGGER.error("Successfully rolled back branch " + branchSession);
+                        LOGGER.error("Successfully rollbacked branch " + branchSession);
                         continue;
                     case PhaseTwo_RollbackFailed_Unretryable:
                         SessionHelper.endRollbackFailed(globalSession);
@@ -306,6 +330,11 @@ public class DefaultCore implements Core {
 
         }
         SessionHelper.endRollbacked(globalSession);
+
+        //rollbacked event
+        eventBus.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
+            globalSession.getTransactionName(), globalSession.getBeginTime(), System.currentTimeMillis(),
+            globalSession.getStatus()));
     }
 
     @Override
diff --git a/server/src/main/java/io/seata/server/event/EventBusManager.java b/server/src/main/java/io/seata/server/event/EventBusManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..2414dbcdb388ee081ecd191b2b0d02412a75fd50
--- /dev/null
+++ b/server/src/main/java/io/seata/server/event/EventBusManager.java
@@ -0,0 +1,34 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.event;
+
+import io.seata.core.event.EventBus;
+import io.seata.core.event.GuavaEventBus;
+
+/**
+ * Manager hold the singleton event bus instance.
+ *
+ * @author zhengyangyong
+ */
+public class EventBusManager {
+    private static class SingletonHolder {
+        private static EventBus INSTANCE = new GuavaEventBus("tc");
+    }
+
+    public static final EventBus get() {
+        return SingletonHolder.INSTANCE;
+    }
+}
diff --git a/server/src/main/java/io/seata/server/lock/LockerFactory.java b/server/src/main/java/io/seata/server/lock/LockerFactory.java
index 7ab260126228a07b32e16c1a83858ecdb087de07..334d5e869cc3837f426da3b092bcb874d05d5e16 100644
--- a/server/src/main/java/io/seata/server/lock/LockerFactory.java
+++ b/server/src/main/java/io/seata/server/lock/LockerFactory.java
@@ -15,19 +15,20 @@
  */
 package io.seata.server.lock;
 
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.sql.DataSource;
-
 import io.seata.common.loader.EnhancedServiceLoader;
 import io.seata.config.Configuration;
 import io.seata.config.ConfigurationFactory;
 import io.seata.core.constants.ConfigurationKeys;
-import io.seata.core.lock.LockMode;
 import io.seata.core.lock.Locker;
+import io.seata.core.store.StoreMode;
 import io.seata.core.store.db.DataSourceGenerator;
 import io.seata.server.session.BranchSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * The type Lock manager factory.
@@ -36,6 +37,11 @@ import io.seata.server.session.BranchSession;
  */
 public class LockerFactory {
 
+    /**
+     * The constant LOGGER.
+     */
+    protected static final Logger LOGGER = LoggerFactory.getLogger(LockerFactory.class);
+
     /**
      * The constant CONFIG.
      */
@@ -72,28 +78,28 @@ public class LockerFactory {
      * @return the lock manager
      */
     public static synchronized final Locker get(BranchSession branchSession) {
-        String lockMode = CONFIG.getConfig(ConfigurationKeys.LOCK_MODE);
-        if (LockMode.DB.name().equalsIgnoreCase(lockMode)) {
-            if (lockerMap.get(lockMode) != null) {
-                return lockerMap.get(lockMode);
+        String storeMode = CONFIG.getConfig(ConfigurationKeys.STORE_MODE);
+        if (StoreMode.DB.name().equalsIgnoreCase(storeMode)) {
+            if (lockerMap.get(storeMode) != null) {
+                return lockerMap.get(storeMode);
             }
             //init dataSource
             String datasourceType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
             DataSourceGenerator dataSourceGenerator = EnhancedServiceLoader.load(DataSourceGenerator.class,
                 datasourceType);
             DataSource logStoreDataSource = dataSourceGenerator.generateDataSource();
-            locker = EnhancedServiceLoader.load(Locker.class, lockMode, new Class[] {DataSource.class},
+            locker = EnhancedServiceLoader.load(Locker.class, storeMode, new Class[] {DataSource.class},
                 new Object[] {logStoreDataSource});
-            lockerMap.put(lockMode, locker);
-        } else if (LockMode.MEMORY.name().equalsIgnoreCase(lockMode)) {
+            lockerMap.put(storeMode, locker);
+        } else if (StoreMode.FILE.name().equalsIgnoreCase(storeMode)) {
             if (branchSession == null) {
-                throw new IllegalArgumentException("branchSession can be null for memory lockMode.");
+                throw new IllegalArgumentException("branchSession can be null for memory/file locker.");
             }
-            locker = EnhancedServiceLoader.load(Locker.class, lockMode,
+            locker = EnhancedServiceLoader.load(Locker.class, storeMode,
                 new Class[] {BranchSession.class}, new Object[] {branchSession});
         } else {
             //other locker
-            locker = EnhancedServiceLoader.load(Locker.class, lockMode);
+            locker = EnhancedServiceLoader.load(Locker.class, storeMode);
         }
         return locker;
     }
diff --git a/server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java b/server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java
index 3539f46638787d20b5a064d4d30d37d43a799f64..2077b01ebc345e37a96a26085f934678f13894ce 100644
--- a/server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java
+++ b/server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java
@@ -26,6 +26,7 @@ import io.seata.core.lock.AbstractLocker;
 import io.seata.core.lock.LockMode;
 import io.seata.core.lock.RowLock;
 import io.seata.core.store.LockStore;
+import io.seata.core.store.StoreMode;
 
 /**
  * The type Data base locker.
@@ -50,7 +51,7 @@ public class DataBaseLocker extends AbstractLocker {
      * @param logStoreDataSource the log store data source
      */
     public DataBaseLocker(DataSource logStoreDataSource) {
-        lockStore = EnhancedServiceLoader.load(LockStore.class, LockMode.DB.name(), new Class[] {DataSource.class},
+        lockStore = EnhancedServiceLoader.load(LockStore.class, StoreMode.DB.name(), new Class[] {DataSource.class},
             new Object[] {logStoreDataSource});
     }
 
diff --git a/server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java b/server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java
index 12976a699c91c37a4c49a558f23fcca8fa2981c4..9af0d2f0e91288910d39959b5c777efb45550a52 100644
--- a/server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java
+++ b/server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java
@@ -36,7 +36,7 @@ import io.seata.server.session.BranchSession;
  * @author zhangsen
  * @data 2019 -05-15
  */
-@LoadLevel(name = "memory")
+@LoadLevel(name = "file")
 public class MemoryLocker extends AbstractLocker {
 
     private static final int BUCKET_PER_TABLE = 128;
diff --git a/server/src/main/java/io/seata/server/metrics/MeterIdConstants.java b/server/src/main/java/io/seata/server/metrics/MeterIdConstants.java
new file mode 100644
index 0000000000000000000000000000000000000000..afed7180952cdd51a38aab8563a2b27949d7410e
--- /dev/null
+++ b/server/src/main/java/io/seata/server/metrics/MeterIdConstants.java
@@ -0,0 +1,61 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.metrics;
+
+import io.seata.metrics.IdConstants;
+import io.seata.metrics.Id;
+
+/**
+ * Constants for meter id in tc
+ *
+ * @author zhengyangyong
+ */
+public class MeterIdConstants {
+    public static final Id COUNTER_ACTIVE = new Id(IdConstants.SEATA_TRANSACTION)
+        .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
+        .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
+        .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ACTIVE);
+
+    public static final Id COUNTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
+        .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
+        .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
+        .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
+
+    public static final Id COUNTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
+        .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
+        .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
+        .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
+
+    public static final Id SUMMARY_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
+        .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
+        .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
+        .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
+
+    public static final Id SUMMARY_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
+        .withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
+        .withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
+        .withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
+
+    public static final Id TIMER_COMMITTED = 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_COMMITTED);
+
+    public static final Id TIMER_ROLLBACK = 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/io/seata/server/metrics/MetricsManager.java b/server/src/main/java/io/seata/server/metrics/MetricsManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ea9055c008f75e1f70e0077711050ad78db0959
--- /dev/null
+++ b/server/src/main/java/io/seata/server/metrics/MetricsManager.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.metrics;
+
+import java.util.List;
+
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+import io.seata.metrics.exporter.Exporter;
+import io.seata.metrics.exporter.ExporterFactory;
+import io.seata.metrics.registry.Registry;
+import io.seata.metrics.registry.RegistryFactory;
+import io.seata.server.event.EventBusManager;
+
+/**
+ * Metrics manager for init
+ *
+ * @author zhengyangyong
+ */
+public class MetricsManager {
+    private static class SingletonHolder {
+        private static MetricsManager INSTANCE = new MetricsManager();
+    }
+
+    public static final MetricsManager get() {
+        return MetricsManager.SingletonHolder.INSTANCE;
+    }
+
+    private Registry registry;
+
+    public Registry getRegistry() {
+        return registry;
+    }
+
+    public void init() {
+        boolean enabled = ConfigurationFactory.getInstance().getBoolean(
+            ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_ENABLED, false);
+        if (enabled) {
+            registry = RegistryFactory.getInstance();
+            if (registry != null) {
+                List<Exporter> exporters = ExporterFactory.getInstanceList();
+                //only at least one metrics exporter implement had imported in pom then need register MetricsSubscriber
+                if (exporters.size() != 0) {
+                    exporters.forEach(exporter -> exporter.setRegistry(registry));
+                    EventBusManager.get().register(new MetricsSubscriber(registry));
+                }
+            }
+        }
+    }
+}
diff --git a/server/src/main/java/io/seata/server/metrics/MetricsSubscriber.java b/server/src/main/java/io/seata/server/metrics/MetricsSubscriber.java
new file mode 100644
index 0000000000000000000000000000000000000000..efc1d0d5900b75eee3568542bd4292418d9e5e25
--- /dev/null
+++ b/server/src/main/java/io/seata/server/metrics/MetricsSubscriber.java
@@ -0,0 +1,93 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.metrics;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+import com.google.common.eventbus.Subscribe;
+import io.seata.core.event.GlobalTransactionEvent;
+import io.seata.core.model.GlobalStatus;
+import io.seata.metrics.registry.Registry;
+
+/**
+ * Event subscriber for metrics
+ *
+ * @author zhengyangyong
+ */
+public class MetricsSubscriber {
+    private final Registry registry;
+
+    private final Map<GlobalStatus, Consumer<GlobalTransactionEvent>> consumers;
+
+    public MetricsSubscriber(Registry registry) {
+        this.registry = registry;
+        consumers = new HashMap<>();
+        consumers.put(GlobalStatus.Begin, this::processGlobalStatusBegin);
+        consumers.put(GlobalStatus.Committed, this::processGlobalStatusCommitted);
+        consumers.put(GlobalStatus.Rollbacked, this::processGlobalStatusRollbacked);
+
+        consumers.put(GlobalStatus.CommitFailed, this::processGlobalStatusCommitFailed);
+        consumers.put(GlobalStatus.RollbackFailed, this::processGlobalStatusRollbackFailed);
+        consumers.put(GlobalStatus.TimeoutRollbacked, this::processGlobalStatusTimeoutRollbacked);
+        consumers.put(GlobalStatus.TimeoutRollbackFailed, this::processGlobalStatusTimeoutRollbackFailed);
+    }
+
+    private void processGlobalStatusBegin(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).increase(1);
+    }
+
+    private void processGlobalStatusCommitted(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+        registry.getCounter(MeterIdConstants.COUNTER_COMMITTED).increase(1);
+        registry.getSummary(MeterIdConstants.SUMMARY_COMMITTED).increase(1);
+        registry.getTimer(MeterIdConstants.TIMER_COMMITTED).record(event.getEndTime() - event.getBeginTime(),
+            TimeUnit.MILLISECONDS);
+    }
+
+    private void processGlobalStatusRollbacked(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+        registry.getCounter(MeterIdConstants.COUNTER_ROLLBACKED).increase(1);
+        registry.getSummary(MeterIdConstants.SUMMARY_ROLLBACKED).increase(1);
+        registry.getTimer(MeterIdConstants.TIMER_ROLLBACK).record(event.getEndTime() - event.getBeginTime(),
+            TimeUnit.MILLISECONDS);
+    }
+
+    private void processGlobalStatusCommitFailed(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+    }
+
+    private void processGlobalStatusRollbackFailed(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+    }
+
+    private void processGlobalStatusTimeoutRollbacked(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+    }
+
+    private void processGlobalStatusTimeoutRollbackFailed(GlobalTransactionEvent event) {
+        registry.getCounter(MeterIdConstants.COUNTER_ACTIVE).decrease(1);
+    }
+
+    @Subscribe
+    public void recordGlobalTransactionEventForMetrics(GlobalTransactionEvent event) {
+        if (registry != null && consumers.containsKey(event.getStatus())) {
+            consumers.get(event.getStatus()).accept(event);
+        }
+    }
+}
diff --git a/server/src/main/java/io/seata/server/session/BranchSession.java b/server/src/main/java/io/seata/server/session/BranchSession.java
index a380eb0b2261904c774ed5848902ca10f65ef853..d3ee02b6350197cdc46b628ce181e43c0e7e3b70 100644
--- a/server/src/main/java/io/seata/server/session/BranchSession.java
+++ b/server/src/main/java/io/seata/server/session/BranchSession.java
@@ -290,6 +290,8 @@ public class BranchSession implements Lockable, Comparable<BranchSession>, Sessi
 
         byte[] xidBytes = xid != null ? xid.getBytes() : null;
 
+        byte branchTypeByte = branchType != null ? (byte) branchType.ordinal() : -1;
+
         int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes, xidBytes);
 
         if (size > MAX_BRANCH_SESSION_SIZE) {
@@ -356,6 +358,8 @@ public class BranchSession implements Lockable, Comparable<BranchSession>, Sessi
             byteBuffer.putInt(0);
         }
 
+        byteBuffer.put(branchTypeByte);
+
         byteBuffer.put((byte)status.getCode());
         byteBuffer.flip();
         byte[] result = new byte[byteBuffer.limit()];
@@ -376,7 +380,8 @@ public class BranchSession implements Lockable, Comparable<BranchSession>, Sessi
             + (lockKeyBytes == null ? 0 : lockKeyBytes.length)
             + (clientIdBytes == null ? 0 : clientIdBytes.length)
             + (applicationDataBytes == null ? 0 : applicationDataBytes.length)
-            + (xidBytes == null ? 0 : xidBytes.length);
+            + (xidBytes == null ? 0 : xidBytes.length)
+            + 1; //branchType
         return size;
     }
 
@@ -424,6 +429,10 @@ public class BranchSession implements Lockable, Comparable<BranchSession>, Sessi
             byteBuffer.get(xidBytes);
             this.xid = new String(xidBytes);
         }
+        int branchTypeId = byteBuffer.get();
+        if (branchTypeId >= 0) {
+            this.branchType = BranchType.values()[branchTypeId];
+        }
         this.status = BranchStatus.get(byteBuffer.get());
 
     }
diff --git a/server/src/main/java/io/seata/server/session/GlobalSession.java b/server/src/main/java/io/seata/server/session/GlobalSession.java
index 8c3cb2dc633e56dadab508a9e65b30b2a267b97f..e6cccff2d353570d57f437a6f2f278f1aba010ad 100644
--- a/server/src/main/java/io/seata/server/session/GlobalSession.java
+++ b/server/src/main/java/io/seata/server/session/GlobalSession.java
@@ -18,6 +18,8 @@ package io.seata.server.session;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -68,7 +70,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
 
     private boolean active = true;
 
-    private ArrayList<BranchSession> branchSessions = new ArrayList<>();
+    private final ArrayList<BranchSession> branchSessions = new ArrayList<>();
 
     private GlobalSessionLock globalSessionLock = new GlobalSessionLock();
 
@@ -92,7 +94,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
         return branchSessions.remove(branchSession);
     }
 
-    private ArrayList<SessionLifecycleListener> lifecycleListeners = new ArrayList<>();
+    private Set<SessionLifecycleListener> lifecycleListeners = new HashSet<>();
 
     /**
      * Can be committed async boolean.
@@ -249,8 +251,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
      * @return the sorted branches
      */
     public ArrayList<BranchSession> getSortedBranches() {
-        ArrayList<BranchSession> sorted = new ArrayList();
-        sorted.addAll(branchSessions);
+        ArrayList<BranchSession> sorted = new ArrayList<>(branchSessions);
         return sorted;
     }
 
@@ -260,8 +261,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
      * @return the reverse sorted branches
      */
     public ArrayList<BranchSession> getReverseSortedBranches() {
-        ArrayList<BranchSession> reversed = new ArrayList();
-        reversed.addAll(branchSessions);
+        ArrayList<BranchSession> reversed = new ArrayList<>(branchSessions);
         Collections.reverse(reversed);
         return reversed;
     }
@@ -507,7 +507,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
 
     private int calGlobalSessionSize(byte[] byApplicationIdBytes, byte[] byServiceGroupBytes, byte[] byTxNameBytes,
                                      byte[] xidBytes, byte[] applicationDataBytes) {
-        final int size = 8 // trascationId
+        final int size = 8 // transactionId
             + 4 // timeout
             + 2 // byApplicationIdBytes.length
             + 2 // byServiceGroupBytes.length
@@ -601,11 +601,11 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
 
         private Lock globalSessionLock = new ReentrantLock();
 
-        private static final int GLOBAL_SESSOION_LOCK_TIME_OUT_MILLS = 2 * 1000;
+        private static final int GLOBAL_SESSION_LOCK_TIME_OUT_MILLS = 2 * 1000;
 
         public void lock() throws TransactionException {
             try {
-                if (globalSessionLock.tryLock(GLOBAL_SESSOION_LOCK_TIME_OUT_MILLS, TimeUnit.MILLISECONDS)) {
+                if (globalSessionLock.tryLock(GLOBAL_SESSION_LOCK_TIME_OUT_MILLS, TimeUnit.MILLISECONDS)) {
                     return;
                 }
             } catch (InterruptedException e) {
diff --git a/server/src/main/java/io/seata/server/session/SessionHolder.java b/server/src/main/java/io/seata/server/session/SessionHolder.java
index c09e746c7855158adaf942fd78036ccccb9f7cf2..7770798832ee1e735f446f0b868eff8039bc231a 100644
--- a/server/src/main/java/io/seata/server/session/SessionHolder.java
+++ b/server/src/main/java/io/seata/server/session/SessionHolder.java
@@ -91,13 +91,10 @@ public class SessionHolder {
             ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, StoreMode.DB.name());
             ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, StoreMode.DB.name(),
                 new Object[] {ASYNC_COMMITTING_SESSION_MANAGER_NAME});
-            ;
             RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, StoreMode.DB.name(),
                 new Object[] {RETRY_COMMITTING_SESSION_MANAGER_NAME});
-            ;
             RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, StoreMode.DB.name(),
                 new Object[] {RETRY_ROLLBACKING_SESSION_MANAGER_NAME});
-            ;
         } else if (StoreMode.FILE.equals(storeMode)) {
             //file store
             String sessionStorePath = CONFIG.getConfig(ConfigurationKeys.STORE_FILE_DIR);
@@ -108,13 +105,10 @@ public class SessionHolder {
                 new Object[] {ROOT_SESSION_MANAGER_NAME, sessionStorePath});
             ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, DEFAULT,
                 new Object[] {ASYNC_COMMITTING_SESSION_MANAGER_NAME});
-            ;
             RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, DEFAULT,
                 new Object[] {RETRY_COMMITTING_SESSION_MANAGER_NAME});
-            ;
             RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, DEFAULT,
                 new Object[] {RETRY_ROLLBACKING_SESSION_MANAGER_NAME});
-            ;
         } else {
             //unknown store
             throw new IllegalArgumentException("unknown store mode:" + mode);
diff --git a/server/src/main/resources/db_store.sql b/server/src/main/resources/db_store.sql
index 78b4fa01871b0213c99309239ca3a6f119c4119a..85fb95e17a067aaba4154787b56d101f2491d4cd 100644
--- a/server/src/main/resources/db_store.sql
+++ b/server/src/main/resources/db_store.sql
@@ -1,5 +1,5 @@
 -- the table to store GlobalSession data
-drop table `global_table`;
+drop table if exists `global_table`;
 create table `global_table` (
   `xid` varchar(128)  not null,
   `transaction_id` bigint,
@@ -18,7 +18,7 @@ create table `global_table` (
 );
 
 -- the table to store BranchSession data
-drop table `branch_table`;
+drop table if exists `branch_table`;
 create table `branch_table` (
   `branch_id` bigint not null,
   `xid` varchar(128) not null,
@@ -37,7 +37,7 @@ create table `branch_table` (
 );
 
 -- the table to store lock data
-drop table `lock_table`;
+drop table if exists `lock_table`;
 create table `lock_table` (
   `row_key` varchar(128) not null,
   `xid` varchar(96),
diff --git a/server/src/main/resources/file.conf b/server/src/main/resources/file.conf
index cc84f7ae44323987a8810b7bf9ddd1fe49ec90bc..da6b0dddd5ffcf27b8c01871de6cb7a1eb4baa92 100644
--- a/server/src/main/resources/file.conf
+++ b/server/src/main/resources/file.conf
@@ -19,6 +19,12 @@ transport {
     #auto default pin or 8
     worker-thread-size = 8
   }
+  shutdown {
+    # when destroy server, wait seconds
+    wait = 3
+  }
+  serialization = "seata"
+  compressor = "none"
 }
 service {
   #vgroup->rgroup
@@ -66,45 +72,50 @@ store {
 
   ## database store
   db {
-      ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
-      datasource = "dbcp"
-      ## mysql/oracle/h2/oceanbase etc.
-      db-type = "mysql"
-      url = "jdbc:mysql://127.0.0.1:3306/seata"
-      user = "mysql"
-      password = "mysql"
-      min-conn = 1
-      max-conn = 3
-      global.table = "global_table"
-      branch.table = "branch_table"
-      query-limit = 100
-    }
+    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
+    datasource = "dbcp"
+    ## mysql/oracle/h2/oceanbase etc.
+    db-type = "mysql"
+    url = "jdbc:mysql://127.0.0.1:3306/seata"
+    user = "mysql"
+    password = "mysql"
+    min-conn = 1
+    max-conn = 3
+    global.table = "global_table"
+    branch.table = "branch_table"
+    lock-table = "lock_table"
+    query-limit = 100
+  }
 }
 lock {
-    ## the data row lock store mode: local_db、memory or db
-    mode = "memory"
+  ## the lock store mode: local、remote
+  mode = "remote"
 
-    memory{
-         ## store lock in memory of server
-    }
-
-    db{
-        ## use db of server to store lock, the db is ${store.db.url}
-        lock-table= "lock_table"
-    }
+  local {
+    ## store locks in user's database
+  }
 
-    local_db {
-        ## store lock in local db
-    }
+  remote {
+    ## store locks in the seata's server
+  }
 }
-recovery{
-    committing-retry-delay = 5
-    asyn-committing-retry-delay = 5
-    rollbacking-retry-delay = 5
-    timeout-retry-delay = 5
+recovery {
+  committing-retry-delay = 30
+  asyn-committing-retry-delay = 30
+  rollbacking-retry-delay = 30
+  timeout-retry-delay = 30
 }
 
 transaction {
   undo.data.validation = true
-  undo.log.serialization = fastjson
+  undo.log.serialization = "jackson"
+}
+
+## metrics settings
+metrics {
+  enabled = false
+  registry-type = "compact"
+  # multi exporters use comma divided
+  exporter-list = "prometheus"
+  exporter-prometheus-port = 9898
 }
\ No newline at end of file
diff --git a/server/src/main/resources/nacos-config.py b/server/src/main/resources/nacos-config.py
new file mode 100755
index 0000000000000000000000000000000000000000..edd10b02802e2929a140151fff9dd41803975efc
--- /dev/null
+++ b/server/src/main/resources/nacos-config.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+#  -*- coding: UTF-8 -*-
+
+import http.client
+import sys
+
+if len(sys.argv) != 2:
+    print ('python nacos-config.py nacosIp')
+    exit()
+
+headers = {
+    'content-type': "application/x-www-form-urlencoded"
+}
+
+hasError = False
+for line in open('nacos-config.txt'):
+    pair = line.split('=')
+    if len(pair) != 2:
+        continue
+    print (line),
+    url_prefix = sys.argv[1] + ':8848'
+    conn = http.client.HTTPConnection(url_prefix)
+    url_postfix = '/nacos/v1/cs/configs?dataId={}&group=SEATA_GROUP&content={}'.format(str(pair[0]),str(pair[1])).strip()
+    conn.request("POST", url_postfix, headers=headers)
+    res = conn.getresponse()
+    data = res.read()
+    if data.decode("utf-8") != "true":
+        hasError = True
+if hasError:
+    print ("init nacos config fail.")
+else:
+    print ("init nacos config finished, please start seata-server.")
\ No newline at end of file
diff --git a/server/src/main/resources/nacos-config.txt b/server/src/main/resources/nacos-config.txt
index ce27a02b70fe9ebb6c0688ab70f1abef7d20bf27..62406d65e46463205925116be3b2b825092515b6 100644
--- a/server/src/main/resources/nacos-config.txt
+++ b/server/src/main/resources/nacos-config.txt
@@ -10,6 +10,7 @@ transport.thread-factory.client-selector-thread-size=1
 transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
 transport.thread-factory.boss-thread-size=1
 transport.thread-factory.worker-thread-size=8
+transport.shutdown.wait=3
 service.vgroup_mapping.my_test_tx_group=default
 service.enableDegrade=false
 service.disable=false
@@ -35,12 +36,17 @@ store.db.max-conn=3
 store.db.global.table=global_table
 store.db.branch.table=branch_table
 store.db.query-limit=100
-lock.mode=memory
-lock.db.lock-table=lock_table
-recovery.committing-retry-delay=5
-recovery.asyn-committing-retry-delay=5
-recovery.rollbacking-retry-delay=5
-recovery.timeout-retry-delay=5
+store.db.lock-table=lock_table
+recovery.committing-retry-delay=30
+recovery.asyn-committing-retry-delay=30
+recovery.rollbacking-retry-delay=30
+recovery.timeout-retry-delay=30
 transaction.undo.data.validation=true
-transaction.undo.log.serialization=fastjson
+transaction.undo.log.serialization=jackson
+transport.serialization=seata
+transport.compressor=none
+metrics.enabled=false
+metrics.registry-type=compact
+metrics.exporter-list=prometheus
+metrics.exporter-prometheus-port=9898
 
diff --git a/server/src/test/java/io/seata/server/ParameterParserTest.java b/server/src/test/java/io/seata/server/ParameterParserTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..259cf7fdd5103b865a920a1db0b40e586b6e7657
--- /dev/null
+++ b/server/src/test/java/io/seata/server/ParameterParserTest.java
@@ -0,0 +1,74 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The type parameter parser test
+ *
+ * @author xingfudeshi@gmail.com
+ * @date 2019/05/30
+ */
+public class ParameterParserTest {
+    private static ParameterParser parameterParser = null;
+
+    /**
+     * init
+     */
+    @BeforeAll
+    private static void init() {
+        String[] args = new String[]{"-h", "127.0.0.1", "-p", "8088", "-m", "file"};
+        parameterParser = new ParameterParser(args);
+    }
+
+    /**
+     * test get host
+     */
+    @Test
+    public void testGetHost() {
+        Assertions.assertEquals("127.0.0.1", parameterParser.getHost());
+    }
+
+    /**
+     * test get port
+     */
+    @Test
+    public void testGetPort() {
+        Assertions.assertEquals(8088, parameterParser.getPort());
+    }
+
+    /**
+     * test get store mode
+     */
+    @Test
+    public void testGetStoreMode() {
+        Assertions.assertEquals("file", parameterParser.getStoreMode());
+    }
+
+    /**
+     * clean up
+     */
+    @AfterAll
+    public static void cleanUp() {
+        parameterParser = null;
+    }
+
+
+}
diff --git a/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorMetricsTest.java b/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorMetricsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..18182dcebba7b30af6d856fecad458bdee3e5bab
--- /dev/null
+++ b/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorMetricsTest.java
@@ -0,0 +1,134 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.coordinator;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import io.seata.core.exception.TransactionException;
+import io.seata.core.protocol.transaction.GlobalBeginRequest;
+import io.seata.core.protocol.transaction.GlobalBeginResponse;
+import io.seata.core.protocol.transaction.GlobalCommitRequest;
+import io.seata.core.protocol.transaction.GlobalCommitResponse;
+import io.seata.core.protocol.transaction.GlobalRollbackRequest;
+import io.seata.core.protocol.transaction.GlobalRollbackResponse;
+import io.seata.core.rpc.RpcContext;
+import io.seata.metrics.Measurement;
+import io.seata.server.metrics.MetricsManager;
+import io.seata.server.session.SessionHolder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test Metrics
+ *
+ * @author zhengyangyong
+ */
+public class DefaultCoordinatorMetricsTest {
+    @Test
+    public void test() throws IOException, TransactionException, InterruptedException {
+        SessionHolder.init(null);
+        DefaultCoordinator coordinator = new DefaultCoordinator(null);
+        coordinator.init();
+
+        MetricsManager.get().init();
+
+        //start a transaction
+        GlobalBeginRequest request = new GlobalBeginRequest();
+        request.setTransactionName("test_transaction");
+        GlobalBeginResponse response = new GlobalBeginResponse();
+        coordinator.doGlobalBegin(request, response, new RpcContext());
+
+        Map<String, Measurement> measurements = new HashMap<>();
+        MetricsManager.get().getRegistry().measure().forEach(
+            measurement -> measurements.put(measurement.getId().toString(), measurement));
+
+        Assertions.assertEquals(1, measurements.size());
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=counter,role=tc,status=active)").getValue(), 0);
+
+        //commit this transaction
+        GlobalCommitRequest commitRequest = new GlobalCommitRequest();
+        commitRequest.setXid(response.getXid());
+        coordinator.doGlobalCommit(commitRequest, new GlobalCommitResponse(), new RpcContext());
+
+        //we need sleep for a short while because default canBeCommittedAsync() is true
+        Thread.sleep(1000);
+
+        measurements.clear();
+        MetricsManager.get().getRegistry().measure().forEach(
+            measurement -> measurements.put(measurement.getId().toString(), measurement));
+        Assertions.assertEquals(9, measurements.size());
+        Assertions.assertEquals(0,
+            measurements.get("seata.transaction(meter=counter,role=tc,status=active)").getValue(), 0);
+        Assertions
+            .assertEquals(1, measurements.get("seata.transaction(meter=counter,role=tc,status=committed)").getValue(),
+                0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=count,status=committed)").getValue(),
+            0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=total,status=committed)").getValue(),
+            0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=timer,role=tc,statistic=count,status=committed)").getValue(), 0);
+
+        //start another new transaction
+        request = new GlobalBeginRequest();
+        request.setTransactionName("test_transaction_2");
+        response = new GlobalBeginResponse();
+        coordinator.doGlobalBegin(request, response, new RpcContext());
+
+        //rollback this transaction
+        GlobalRollbackRequest rollbackRequest = new GlobalRollbackRequest();
+        rollbackRequest.setXid(response.getXid());
+        coordinator.doGlobalRollback(rollbackRequest, new GlobalRollbackResponse(), new RpcContext());
+
+        Thread.sleep(1000);
+
+        measurements.clear();
+        MetricsManager.get().getRegistry().measure().forEach(
+            measurement -> measurements.put(measurement.getId().toString(), measurement));
+        Assertions.assertEquals(17, measurements.size());
+        Assertions.assertEquals(0,
+            measurements.get("seata.transaction(meter=counter,role=tc,status=active)").getValue(), 0);
+
+        Assertions
+            .assertEquals(1, measurements.get("seata.transaction(meter=counter,role=tc,status=committed)").getValue(),
+                0);
+        Assertions.assertEquals(0,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=count,status=committed)").getValue(),
+            0);
+        Assertions.assertEquals(0,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=total,status=committed)").getValue(),
+            0);
+        Assertions.assertEquals(0,
+            measurements.get("seata.transaction(meter=timer,role=tc,statistic=count,status=committed)").getValue(), 0);
+
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=counter,role=tc,status=rollbacked)").getValue(), 0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=count,status=rollbacked)").getValue(),
+            0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=summary,role=tc,statistic=total,status=rollbacked)").getValue(),
+            0);
+        Assertions.assertEquals(1,
+            measurements.get("seata.transaction(meter=timer,role=tc,statistic=count,status=rollbacked)").getValue(), 0);
+    }
+
+}
diff --git a/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorTest.java b/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorTest.java
index d5a03ece98313ab5f94c451669d2a646f9ca9fa5..feef449593e7c4241bf384e2b2d3295c397acbf7 100644
--- a/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorTest.java
+++ b/server/src/test/java/io/seata/server/coordinator/DefaultCoordinatorTest.java
@@ -21,6 +21,7 @@ import io.seata.common.util.NetUtil;
 import io.seata.core.exception.TransactionException;
 import io.seata.core.model.BranchStatus;
 import io.seata.core.model.BranchType;
+import io.seata.core.protocol.RpcMessage;
 import io.seata.core.protocol.transaction.BranchCommitRequest;
 import io.seata.core.protocol.transaction.BranchCommitResponse;
 import io.seata.core.protocol.transaction.BranchRollbackRequest;
@@ -83,7 +84,7 @@ public class DefaultCoordinatorTest {
 
     @ParameterizedTest
     @MethodSource("xidAndBranchIdProviderForCommit")
-    public void branchCommit(String xid, Long branchId) {
+    public void branchCommit(String xid, Long branchId) throws TransactionException {
         BranchStatus result = null;
 
         try {
@@ -93,6 +94,10 @@ public class DefaultCoordinatorTest {
         }
         Assertions.assertEquals(result, BranchStatus.PhaseTwo_Committed);
 
+        //clear
+        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        Assertions.assertNotNull(globalSession);
+        globalSession.end();
     }
     @Disabled
     @ParameterizedTest
@@ -157,7 +162,7 @@ public class DefaultCoordinatorTest {
     private static class MockServerMessageSender implements ServerMessageSender {
 
         @Override
-        public void sendResponse(long msgId, Channel channel, Object msg) {
+        public void sendResponse(RpcMessage request, Channel channel, Object msg) {
 
         }
 
diff --git a/server/src/test/java/io/seata/server/coordinator/DefaultCoreTest.java b/server/src/test/java/io/seata/server/coordinator/DefaultCoreTest.java
index 8569001e89a9ed038f70147c035337c860673ae4..71ef3568c51c218a631a14bc9ff31d5a8621d113 100644
--- a/server/src/test/java/io/seata/server/coordinator/DefaultCoreTest.java
+++ b/server/src/test/java/io/seata/server/coordinator/DefaultCoreTest.java
@@ -15,7 +15,9 @@
  */
 package io.seata.server.coordinator;
 
-import io.seata.common.XID;
+import java.util.Collection;
+import java.util.stream.Stream;
+
 import io.seata.core.exception.TransactionException;
 import io.seata.core.model.BranchStatus;
 import io.seata.core.model.BranchType;
@@ -33,9 +35,6 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import java.util.Collection;
-import java.util.stream.Stream;
-
 /**
  * The type Default core test.
  *
@@ -58,12 +57,14 @@ public class DefaultCoreTest {
 
     private static final String clientId = "c_1";
 
-    private static final String lockKeys_1 = "tb_1:11";
+    private static final String lockKeys_1 = "tb_11:11";
 
-    private static final String lockKeys_2 = "tb_1:12";
+    private static final String lockKeys_2 = "tb_12:12";
 
     private static final String applicationData = "{\"data\":\"test\"}";
 
+    private GlobalSession globalSession;
+
     /**
      * Init session manager.
      *
@@ -74,6 +75,19 @@ public class DefaultCoreTest {
         SessionHolder.init(null);
     }
 
+    /**
+     * Clean.
+     *
+     * @throws TransactionException the transaction exception
+     */
+    @AfterEach
+    public void clean() throws TransactionException {
+        if (null != globalSession) {
+            globalSession.end();
+            globalSession = null;
+        }
+    }
+
     /**
      * Branch register test.
      *
@@ -84,12 +98,8 @@ public class DefaultCoreTest {
     @MethodSource("xidProvider")
     public void branchRegisterTest(String xid) throws Exception {
         core.branchRegister(BranchType.AT, resourceId, clientId, xid, "abc", lockKeys_1);
-        long transactionId = XID.getTransactionId(xid);
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         Assertions.assertEquals(globalSession.getSortedBranches().size(), 1);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -103,13 +113,9 @@ public class DefaultCoreTest {
     @MethodSource("xidAndBranchIdProvider")
     public void branchReportTest(String xid, Long branchId) throws Exception {
         core.branchReport(BranchType.AT, xid, branchId, BranchStatus.PhaseOne_Done, applicationData);
-        long transactionId = XID.getTransactionId(xid);
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = globalSession.getBranch(branchId);
         Assertions.assertEquals(branchSession.getStatus(), BranchStatus.PhaseOne_Done);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -120,13 +126,9 @@ public class DefaultCoreTest {
     @Test
     public void beginTest() throws Exception {
         String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
-        long transactionId = XID.getTransactionId(xid);
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         Assertions.assertNotNull(globalSession);
 
-        //clear
-        globalSession.end();
-
     }
 
     /**
@@ -151,20 +153,17 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalCommitCommitTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseOne_Done));
+        core.setResourceManagerInbound(
+            new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseOne_Done));
         core.doGlobalCommit(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.Committed);
-
-        //clear
-        globalSession.end();
     }
 
-
     /**
      * Do global commit test.
      *
@@ -174,17 +173,15 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalCommitUnretryableTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_CommitFailed_Unretryable, BranchStatus.PhaseOne_Done));
+        core.setResourceManagerInbound(
+            new MockResourceManagerInbound(BranchStatus.PhaseTwo_CommitFailed_Unretryable, BranchStatus.PhaseOne_Done));
         core.doGlobalCommit(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.Begin);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -196,17 +193,15 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalCommitExpTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseOne_Timeout, BranchStatus.PhaseOne_Done));
+        core.setResourceManagerInbound(
+            new MockResourceManagerInbound(BranchStatus.PhaseOne_Timeout, BranchStatus.PhaseOne_Done));
         core.doGlobalCommit(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.CommitRetrying);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -231,20 +226,17 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalRollBackRollbackedTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseTwo_Rollbacked));
+        core.setResourceManagerInbound(
+            new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseTwo_Rollbacked));
         core.doGlobalRollback(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.Rollbacked);
-
-        //clear
-        globalSession.end();
     }
 
-
     /**
      * Do global roll back test.
      *
@@ -254,17 +246,15 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalRollBackUnretryableTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseTwo_RollbackFailed_Unretryable));
+        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed,
+            BranchStatus.PhaseTwo_RollbackFailed_Unretryable));
         core.doGlobalRollback(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.RollbackFailed);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -276,17 +266,15 @@ public class DefaultCoreTest {
     @ParameterizedTest
     @MethodSource("xidProvider")
     public void doGlobalRollBackRetryableExpTest(String xid) throws Exception {
-        GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+        globalSession = SessionHolder.findGlobalSession(xid);
         BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, BranchType.AT, resourceId,
-                applicationData, "t1:1", clientId);
+            applicationData, "t1:1", clientId);
         globalSession.addBranch(branchSession);
         globalSession.changeBranchStatus(branchSession, BranchStatus.PhaseOne_Done);
-        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed, BranchStatus.PhaseTwo_RollbackFailed_Retryable));
+        core.setResourceManagerInbound(new MockResourceManagerInbound(BranchStatus.PhaseTwo_Committed,
+            BranchStatus.PhaseTwo_RollbackFailed_Retryable));
         core.doGlobalRollback(globalSession, false);
         Assertions.assertEquals(globalSession.getStatus(), GlobalStatus.RollbackRetrying);
-
-        //clear
-        globalSession.end();
     }
 
     /**
@@ -297,8 +285,9 @@ public class DefaultCoreTest {
      */
     static Stream<Arguments> xidProvider() throws Exception {
         String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
+        Assertions.assertNotNull(xid);
         return Stream.of(
-                Arguments.of(xid)
+            Arguments.of(xid)
         );
     }
 
@@ -311,8 +300,10 @@ public class DefaultCoreTest {
     static Stream<Arguments> xidAndBranchIdProvider() throws Exception {
         String xid = core.begin(applicationId, txServiceGroup, txName, timeout);
         Long branchId = core.branchRegister(BranchType.AT, resourceId, clientId, xid, null, lockKeys_2);
+        Assertions.assertNotNull(xid);
+        Assertions.assertTrue(branchId != 0);
         return Stream.of(
-                Arguments.of(xid, branchId)
+            Arguments.of(xid, branchId)
         );
     }
 
@@ -333,24 +324,31 @@ public class DefaultCoreTest {
         }
     }
 
-
     private static class MockResourceManagerInbound implements ResourceManagerInbound {
 
         private BranchStatus commitStatus;
         private BranchStatus rollbackStatus;
 
+        /**
+         * Instantiates a new Mock resource manager inbound.
+         *
+         * @param commitStatus   the commit status
+         * @param rollbackStatus the rollback status
+         */
         public MockResourceManagerInbound(BranchStatus commitStatus, BranchStatus rollbackStatus) {
             this.commitStatus = commitStatus;
             this.rollbackStatus = rollbackStatus;
         }
 
         @Override
-        public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
+        public BranchStatus branchCommit(BranchType branchType, String xid, long branchId, String resourceId,
+                                         String applicationData) throws TransactionException {
             return commitStatus;
         }
 
         @Override
-        public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) throws TransactionException {
+        public BranchStatus branchRollback(BranchType branchType, String xid, long branchId, String resourceId,
+                                           String applicationData) throws TransactionException {
             return rollbackStatus;
         }
     }
diff --git a/server/src/test/java/io/seata/server/event/DefaultCoreForEventBusTest.java b/server/src/test/java/io/seata/server/event/DefaultCoreForEventBusTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..31c76fa5bdd18dc5c9064de59e141cc99a8d93e0
--- /dev/null
+++ b/server/src/test/java/io/seata/server/event/DefaultCoreForEventBusTest.java
@@ -0,0 +1,105 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.server.event;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.google.common.eventbus.Subscribe;
+import io.seata.core.event.GlobalTransactionEvent;
+import io.seata.core.exception.TransactionException;
+import io.seata.core.model.GlobalStatus;
+import io.seata.server.coordinator.Core;
+import io.seata.server.coordinator.CoreFactory;
+import io.seata.server.coordinator.DefaultCoordinator;
+import io.seata.server.session.SessionHolder;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Test events come from Default Core.
+ *
+ * @author zhengyangyong
+ */
+public class DefaultCoreForEventBusTest {
+    @Test
+    public void test() throws IOException, TransactionException, InterruptedException {
+        class GlobalTransactionEventSubscriber {
+            private final Map<GlobalStatus, AtomicInteger> eventCounters;
+
+            public Map<GlobalStatus, AtomicInteger> getEventCounters() {
+                return eventCounters;
+            }
+
+            public GlobalTransactionEventSubscriber() {
+                this.eventCounters = new ConcurrentHashMap<>();
+            }
+
+            @Subscribe
+            public void processGlobalTransactionEvent(GlobalTransactionEvent event) {
+                AtomicInteger counter = eventCounters.computeIfAbsent(event.getStatus(),
+                    status -> new AtomicInteger(0));
+                counter.addAndGet(1);
+            }
+        }
+
+        SessionHolder.init(null);
+        DefaultCoordinator coordinator = new DefaultCoordinator(null);
+        coordinator.init();
+
+        Core core = CoreFactory.get();
+
+        GlobalTransactionEventSubscriber subscriber = new GlobalTransactionEventSubscriber();
+        EventBusManager.get().register(subscriber);
+
+        //start a transaction
+        String xid = core.begin("test_app_id", "default_group", "test_tran_name", 30000);
+
+        Assertions.assertEquals(1, subscriber.getEventCounters().get(GlobalStatus.Begin).get());
+
+        //commit this transaction
+        core.commit(xid);
+
+        //we need sleep for a short while because default canBeCommittedAsync() is true
+        Thread.sleep(1000);
+
+        //check
+        Assertions.assertEquals(1, subscriber.getEventCounters().get(GlobalStatus.AsyncCommitting).get());
+        Assertions.assertEquals(1, subscriber.getEventCounters().get(GlobalStatus.Committed).get());
+
+        //start another new transaction
+        xid = core.begin("test_app_id", "default_group", "test_tran_name2", 30000);
+
+        Assertions.assertEquals(2, subscriber.getEventCounters().get(GlobalStatus.Begin).get());
+
+        core.rollback(xid);
+
+        //check
+        Assertions.assertEquals(1, subscriber.getEventCounters().get(GlobalStatus.Rollbacking).get());
+        Assertions.assertEquals(1, subscriber.getEventCounters().get(GlobalStatus.Rollbacked).get());
+
+        //start more one new transaction for test timeout and let this transaction immediately timeout
+        xid = core.begin("test_app_id", "default_group", "test_tran_name3", 0);
+
+        //sleep for check ->  DefaultCoordinator.timeoutCheck
+        Thread.sleep(1000);
+
+        //at lease retry once because DefaultCoordinator.timeoutCheck is 1 second
+        Assertions.assertTrue(subscriber.getEventCounters().get(GlobalStatus.TimeoutRollbacking).get() >= 1);
+    }
+}
diff --git a/server/src/test/resources/file.conf b/server/src/test/resources/file.conf
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f9e02c81268c65b44bdcc4fc8dba3a2a211dc
--- /dev/null
+++ b/server/src/test/resources/file.conf
@@ -0,0 +1,14 @@
+#reduce delay for test
+recovery {
+  asyn-committing-retry-delay = 1
+  timeout-retry-delay = 1
+}
+
+## metrics settings
+metrics {
+  enabled = true
+  registry-type = "compact"
+  # multi exporters use comma divided
+  exporter-list = "prometheus"
+  exporter-prometheus-port = 9898
+}
\ No newline at end of file
diff --git a/server/src/test/resources/registry.conf b/server/src/test/resources/registry.conf
new file mode 100644
index 0000000000000000000000000000000000000000..8856edda374488cc44f42da8753cda3895eeb3ce
--- /dev/null
+++ b/server/src/test/resources/registry.conf
@@ -0,0 +1,7 @@
+config {
+  type = "file"
+
+  file {
+    name = "file.conf"
+  }
+}
\ No newline at end of file
diff --git a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
index c6c3fe686416ce33759d5486d7efe48bcc876541..703946b0bf716426ed6c7bbdd83001b2480e9f0d 100644
--- a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
+++ b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
@@ -42,9 +42,12 @@ import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.PriorityOrdered;
 
 /**
  * The type Global transaction scanner.
@@ -54,7 +57,7 @@ import org.springframework.context.ConfigurableApplicationContext;
  */
 public class GlobalTransactionScanner extends AbstractAutoProxyCreator
     implements InitializingBean, ApplicationContextAware,
-    DisposableBean {
+    DisposableBean, BeanFactoryPostProcessor, PriorityOrdered {
 
     /**
      *
@@ -297,4 +300,13 @@ public class GlobalTransactionScanner extends AbstractAutoProxyCreator
         this.setBeanFactory(applicationContext);
     }
 
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        //do nothing
+    }
+
+    @Override
+    public int getOrder() {
+        return HIGHEST_PRECEDENCE;
+    }
 }
diff --git a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionalInterceptor.java b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionalInterceptor.java
index b3d7370e3d7f890498acd0aeba5972798a696b59..4b52eb9dca232aeea4d6612565f153eb96e90f12 100644
--- a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionalInterceptor.java
+++ b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionalInterceptor.java
@@ -60,10 +60,8 @@ public class GlobalTransactionalInterceptor implements MethodInterceptor {
      * @param failureHandler the failure handler
      */
     public GlobalTransactionalInterceptor(FailureHandler failureHandler) {
-        if (null == failureHandler) {
-            failureHandler = DEFAULT_FAIL_HANDLER;
-        }
-        this.failureHandler = failureHandler;
+        this.failureHandler = failureHandler == null ? DEFAULT_FAIL_HANDLER : failureHandler;
+
     }
 
     @Override
@@ -158,10 +156,7 @@ public class GlobalTransactionalInterceptor implements MethodInterceptor {
     }
 
     private <T extends Annotation> T getAnnotation(Method method, Class<T> clazz) {
-        if (method == null) {
-            return null;
-        }
-        return method.getAnnotation(clazz);
+        return method == null ? null : method.getAnnotation(clazz);
     }
 
     private String formatMethod(Method method) {
diff --git a/spring/src/main/java/io/seata/spring/tcc/TccActionInterceptor.java b/spring/src/main/java/io/seata/spring/tcc/TccActionInterceptor.java
index 74e0146b0daf9a951c7d5b0f225049380e182d27..cc8b2699d9e86bb46b761a3cac8c215798528526 100644
--- a/spring/src/main/java/io/seata/spring/tcc/TccActionInterceptor.java
+++ b/spring/src/main/java/io/seata/spring/tcc/TccActionInterceptor.java
@@ -15,12 +15,8 @@
  */
 package io.seata.spring.tcc;
 
-import java.lang.reflect.Method;
-import java.util.Map;
-
 import io.seata.common.Constants;
 import io.seata.common.executor.Callback;
-import io.seata.common.util.StringUtils;
 import io.seata.core.context.RootContext;
 import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
 import io.seata.rm.tcc.interceptor.ActionInterceptorHandler;
@@ -32,6 +28,9 @@ import org.aopalliance.intercept.MethodInvocation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.Method;
+import java.util.Map;
+
 /**
  * TCC Interceptor
  *
@@ -41,6 +40,9 @@ public class TccActionInterceptor implements MethodInterceptor {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(TccActionInterceptor.class);
 
+    private static final String DUBBO_PROXY_NAME_PREFIX="com.alibaba.dubbo.common.bytecode.proxy";
+
+
     private ActionInterceptorHandler actionInterceptorHandler = new ActionInterceptorHandler();
 
     /**
@@ -65,25 +67,34 @@ public class TccActionInterceptor implements MethodInterceptor {
 
     @Override
     public Object invoke(final MethodInvocation invocation) throws Throwable {
+        if(!RootContext.inGlobalTransaction()){
+            //not in transaction
+            return invocation.proceed();
+        }
         Method method = getActionInterfaceMethod(invocation);
         TwoPhaseBusinessAction businessAction = method.getAnnotation(TwoPhaseBusinessAction.class);
         //try method
         if (businessAction != null) {
-            if (StringUtils.isBlank(RootContext.getXID())) {
-                //not in distribute transaction
-                return invocation.proceed();
+            //save the xid
+            String xid = RootContext.getXID();
+            //clear the context
+            RootContext.unbind();
+            try {
+                Object[] methodArgs = invocation.getArguments();
+                //Handler the TCC Aspect
+                Map<String, Object> ret = actionInterceptorHandler.proceed(method, methodArgs, xid, businessAction,
+                        new Callback<Object>() {
+                            @Override
+                            public Object execute() throws Throwable {
+                                return invocation.proceed();
+                            }
+                        });
+                //return the final result
+                return ret.get(Constants.TCC_METHOD_RESULT);
+            } finally {
+                //recovery the context
+                RootContext.bind(xid);
             }
-            Object[] methodArgs = invocation.getArguments();
-            //Handler the TCC Aspect
-            Map<String, Object> ret = actionInterceptorHandler.proceed(method, methodArgs, businessAction,
-                new Callback<Object>() {
-                    @Override
-                    public Object execute() throws Throwable {
-                        return invocation.proceed();
-                    }
-                });
-            //return the final result
-            return ret.get(Constants.TCC_METHOD_RESULT);
         }
         return invocation.proceed();
     }
@@ -126,7 +137,7 @@ public class TccActionInterceptor implements MethodInterceptor {
      * @throws Exception the exception
      */
     protected Class<?> getProxyInterface(Object proxyBean) throws Exception {
-        if (proxyBean.getClass().getName().startsWith("com.alibaba.dubbo.common.bytecode.proxy")) {
+        if (proxyBean.getClass().getName().startsWith(DUBBO_PROXY_NAME_PREFIX)) {
             //dubbo javaassist proxy
             return DubboUtil.getAssistInterface(proxyBean);
         } else {
diff --git a/spring/src/main/java/io/seata/spring/util/SpringProxyUtils.java b/spring/src/main/java/io/seata/spring/util/SpringProxyUtils.java
index 308502aaa2f4048616fd6c91661b31306bcbc5e3..974065576906aaa6618d3172d04459a1dcb796cd 100644
--- a/spring/src/main/java/io/seata/spring/util/SpringProxyUtils.java
+++ b/spring/src/main/java/io/seata/spring/util/SpringProxyUtils.java
@@ -43,15 +43,12 @@ public class SpringProxyUtils {
             if (AopUtils.isJdkDynamicProxy(proxy)) {
                 TargetSource targetSource = advised.getTargetSource();
                 return targetSource instanceof EmptyTargetSource ? getFirstInterfaceByAdvised(advised)
-                    : targetSource.getTarget().getClass();
+                    : targetSource.getTargetClass();
             }
             Object target = advised.getTargetSource().getTarget();
             return findTargetClass(target);
         } else {
-            if (proxy == null) {
-                return null;
-            }
-            return proxy.getClass();
+            return proxy == null ? null :proxy.getClass();
         }
     }
 
diff --git a/tcc/src/main/java/io/seata/rm/tcc/interceptor/ActionInterceptorHandler.java b/tcc/src/main/java/io/seata/rm/tcc/interceptor/ActionInterceptorHandler.java
index 52e997bf482ca36c7b20c57d16e7f3083dae21d2..5317e67808d0c98f88813e1fc035325195a113ab 100644
--- a/tcc/src/main/java/io/seata/rm/tcc/interceptor/ActionInterceptorHandler.java
+++ b/tcc/src/main/java/io/seata/rm/tcc/interceptor/ActionInterceptorHandler.java
@@ -15,19 +15,11 @@
  */
 package io.seata.rm.tcc.interceptor;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 import com.alibaba.fastjson.JSON;
-
 import io.seata.common.Constants;
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.executor.Callback;
 import io.seata.common.util.NetUtil;
-import io.seata.core.context.RootContext;
 import io.seata.core.model.BranchType;
 import io.seata.rm.DefaultResourceManager;
 import io.seata.rm.tcc.api.BusinessActionContext;
@@ -36,6 +28,12 @@ import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * Handler the TCC Participant Aspect : Setting Context, Creating Branch Record
  *
@@ -55,13 +53,12 @@ public class ActionInterceptorHandler {
      * @return map map
      * @throws Throwable the throwable
      */
-    public Map<String, Object> proceed(Method method, Object[] arguments, TwoPhaseBusinessAction businessAction,
+    public Map<String, Object> proceed(Method method, Object[] arguments, String xid, TwoPhaseBusinessAction businessAction,
                                        Callback<Object> targetCallback) throws Throwable {
         Map<String, Object> ret = new HashMap<String, Object>(16);
 
         //TCC name
         String actionName = businessAction.name();
-        String xid = RootContext.getXID();
         BusinessActionContext actionContext = new BusinessActionContext();
         actionContext.setXid(xid);
         //set action anme
diff --git a/test/pom.xml b/test/pom.xml
index 32dc0ec652be107ba657f428ab1b2270d738b45f..71ea4bde7af2c94c0dc6e3b088f1ff34d21b281d 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -87,8 +87,23 @@
         <dependency>
             <groupId>org.apache.zookeeper</groupId>
             <artifactId>zookeeper</artifactId>
+            <exclusions>
+                <exclusion>
+                    <artifactId>slf4j-log4j12</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+            </exclusions>
         </dependency>
 
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>seata-codec-seata</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
 
diff --git a/test/src/test/java/io/seata/core/rpc/netty/v1/ClientChannelHandler.java b/test/src/test/java/io/seata/core/rpc/netty/v1/ClientChannelHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e74a324574ca76a1fb952b2372536c120a275ff
--- /dev/null
+++ b/test/src/test/java/io/seata/core/rpc/netty/v1/ClientChannelHandler.java
@@ -0,0 +1,68 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.util.concurrent.DefaultPromise;
+import io.seata.core.protocol.RpcMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Geng Zhang
+ */
+public class ClientChannelHandler extends ChannelInboundHandlerAdapter {
+
+    /**
+     * Logger for ClientChannelHandler
+     **/
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientChannelHandler.class);
+
+    private ProtocolV1Client client;
+
+    public ClientChannelHandler(ProtocolV1Client client) {
+        this.client = client;
+    }
+
+    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
+        LOGGER.info("Channel active: {}", ctx.channel());
+    }
+
+    @Override
+    public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
+        LOGGER.info("Channel inactive: {}", ctx.channel());
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        LOGGER.info("response {} ", msg);
+        
+        if (msg instanceof RpcMessage) {
+            RpcMessage rpcMessage = (RpcMessage) msg;
+            int msgId = rpcMessage.getId();
+            DefaultPromise future = (DefaultPromise) client.futureMap.remove(msgId);
+            future.setSuccess(msg);
+        }
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, final Throwable cause) throws Exception {
+        LOGGER.warn("", cause);
+    }
+
+}
diff --git a/test/src/test/java/io/seata/core/rpc/netty/v1/HeadMapSerializerTest.java b/test/src/test/java/io/seata/core/rpc/netty/v1/HeadMapSerializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b41412fe6dc4a39b5471165e127f88656d405d6
--- /dev/null
+++ b/test/src/test/java/io/seata/core/rpc/netty/v1/HeadMapSerializerTest.java
@@ -0,0 +1,95 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Geng Zhang
+ */
+class HeadMapSerializerTest {
+
+    @Test
+    public void encode() throws Exception {
+        HeadMapSerializer simpleMapSerializer = HeadMapSerializer.getInstance();
+        Map<String, String> map = null;
+        int bs = simpleMapSerializer.encode(map, null);
+        Assertions.assertEquals(bs, 0);
+
+        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.heapBuffer();
+        bs = simpleMapSerializer.encode(map, byteBuf);
+        Assertions.assertEquals(bs, 0);
+
+        map = new HashMap<String, String>();
+        bs = simpleMapSerializer.encode(map, byteBuf);
+        Assertions.assertEquals(bs, 0);
+
+        map.put("1", "2");
+        map.put("", "x");
+        map.put("a", "");
+        map.put("b", null);
+        bs = simpleMapSerializer.encode(map, byteBuf);
+        Assertions.assertEquals(21, bs);
+
+        Map<String, String> map1 = simpleMapSerializer.decode(byteBuf, 21);
+        Assertions.assertNotNull(map1);
+        Assertions.assertEquals(4, map1.size());
+        Assertions.assertEquals("2", map1.get("1"));
+        Assertions.assertEquals("x", map1.get(""));
+        Assertions.assertEquals("", map1.get("a"));
+        Assertions.assertEquals(null, map1.get("b"));
+
+        map1 = simpleMapSerializer.decode(byteBuf, 21);
+        Assertions.assertNotNull(map1);
+        Assertions.assertEquals(0, map1.size());
+
+        map1 = simpleMapSerializer.decode(null, 21);
+        Assertions.assertNotNull(map1);
+        Assertions.assertEquals(0, map1.size());
+
+        byteBuf.release();
+    }
+
+    @Test
+    public void testUTF8() throws Exception {
+        HeadMapSerializer mapSerializer = HeadMapSerializer.getInstance();
+        String s = "test";
+        // utf-8 和 gbk  英文是一样的
+        Assertions.assertArrayEquals(s.getBytes("UTF-8"), s.getBytes("GBK"));
+
+        Map<String, String> map = new HashMap<String, String>();
+        map.put("11", "22");
+        map.put("222", "333");
+        ByteBuf byteBuf = ByteBufAllocator.DEFAULT.heapBuffer();
+        int bs = mapSerializer.encode(map, byteBuf);
+        Map newmap = mapSerializer.decode(byteBuf, bs);
+        Assertions.assertEquals(map, newmap);
+
+        // 支持中文
+        map.put("弄啥呢", "咋弄呢?");
+        bs = mapSerializer.encode(map, byteBuf);
+        newmap = mapSerializer.decode(byteBuf, bs);
+        Assertions.assertEquals(map, newmap);
+
+        byteBuf.release();
+    }
+}
\ No newline at end of file
diff --git a/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Client.java b/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Client.java
new file mode 100644
index 0000000000000000000000000000000000000000..3a2cff94875be5d64c9cb216b30f0d45c540aa68
--- /dev/null
+++ b/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Client.java
@@ -0,0 +1,142 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.channel.AdaptiveRecvByteBufAllocator;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.util.concurrent.DefaultEventExecutor;
+import io.netty.util.concurrent.DefaultPromise;
+import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.thread.PositiveAtomicCounter;
+import io.seata.core.codec.CodecType;
+import io.seata.core.model.BranchType;
+import io.seata.core.protocol.ProtocolConstants;
+import io.seata.core.protocol.RpcMessage;
+import io.seata.core.protocol.transaction.BranchCommitRequest;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * @author Geng Zhang
+ */
+public class ProtocolV1Client {
+
+    Channel channel;
+
+    PositiveAtomicCounter idGenerator = new PositiveAtomicCounter();
+
+    Map<Integer, Future> futureMap = new HashMap<>();
+
+    private EventLoopGroup eventLoopGroup = createWorkerGroup();
+
+    public void connect(String host, int port, int connectTimeout) {
+
+        Bootstrap bootstrap = new Bootstrap();
+        bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class);
+        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
+        bootstrap.option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT);
+        bootstrap.option(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 32 * 1024);
+        bootstrap.option(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 8 * 1024);
+        bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT);
+        bootstrap.handler(new ChannelInitializer() {
+            @Override
+            protected void initChannel(Channel channel) throws Exception {
+                ChannelPipeline pipeline = channel.pipeline();
+                pipeline.addLast(new ProtocolV1Encoder());
+                pipeline.addLast(new ProtocolV1Decoder(8 * 1024 * 1024));
+                pipeline.addLast(new ClientChannelHandler(ProtocolV1Client.this));
+            }
+        });
+        // Bind and start to accept incoming connections.
+
+        ChannelFuture channelFuture = bootstrap.connect(host, port);
+        channelFuture.awaitUninterruptibly(connectTimeout, TimeUnit.MILLISECONDS);
+        if (channelFuture.isSuccess()) {
+            channel = channelFuture.channel();
+//            if (NetUtils.toAddressString((InetSocketAddress) channel.remoteAddress())
+//                    .equals(NetUtils.toAddressString((InetSocketAddress) channel.localAddress()))) {
+//                // 服务端不存活时,连接左右两侧地址一样的情况
+//                channel.close(); // 关掉重连
+//                throw new InitErrorException("Failed to connect " + host + ":" + port
+//                        + ". Cause by: Remote and local address are the same");
+//            }
+        } else {
+            Throwable cause = channelFuture.cause();
+            throw new RuntimeException("Failed to connect " + host + ":" + port +
+                    (cause != null ? ". Cause by: " + cause.getMessage() : "."));
+        }
+    }
+
+    private EventLoopGroup createWorkerGroup() {
+        NamedThreadFactory threadName =
+                new NamedThreadFactory("CLI-WORKER", false);
+        return new NioEventLoopGroup(10, threadName);
+    }
+
+    public static void main(String[] args) throws InterruptedException, TimeoutException, ExecutionException {
+        ProtocolV1Client client = new ProtocolV1Client();
+        client.connect("127.0.0.1", 8811, 500);
+
+        Map<String, String> head = new HashMap<>();
+        head.put("tracerId", "xxadadadada");
+        head.put("token", "adadadad");
+
+        BranchCommitRequest body = new BranchCommitRequest();
+        body.setBranchId(12345L);
+        body.setApplicationData("application");
+        body.setBranchType(BranchType.AT);
+        body.setResourceId("resource-1234");
+        body.setXid("xid-1234");
+
+        RpcMessage rpcMessage = new RpcMessage();
+        rpcMessage.setId(client.idGenerator.incrementAndGet());
+        rpcMessage.setCodec(CodecType.SEATA.getCode());
+        rpcMessage.setCompressor(ProtocolConstants.CONFIGURED_COMPRESSOR);
+        rpcMessage.setHeadMap(head);
+        rpcMessage.setBody(body);
+        rpcMessage.setMessageType(ProtocolConstants.MSGTYPE_RESQUEST);
+
+        Future future = client.send(rpcMessage.getId(), rpcMessage);
+        RpcMessage resp = (RpcMessage) future.get(200, TimeUnit.SECONDS);
+
+        System.out.println(resp.getId() + " " + resp.getBody());
+    }
+
+
+    private Future send(int msgId, Object msg) {
+        if (channel != null) {
+            DefaultPromise promise = new DefaultPromise(new DefaultEventExecutor(eventLoopGroup));
+            futureMap.put(msgId, promise);
+            channel.writeAndFlush(msg);
+            return promise;
+        }
+        return null;
+    }
+}
diff --git a/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Server.java b/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Server.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed359183e88bb54935b1e3ae33feb28fbd24ec49
--- /dev/null
+++ b/test/src/test/java/io/seata/core/rpc/netty/v1/ProtocolV1Server.java
@@ -0,0 +1,122 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.channel.AdaptiveRecvByteBufAllocator;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.WriteBufferWaterMark;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+import io.seata.common.thread.NamedThreadFactory;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Geng Zhang
+ */
+public class ProtocolV1Server {
+
+    private int port = 8811;
+    private ServerBootstrap serverBootstrap;
+
+    private EventLoopGroup bossGroup;
+    private EventLoopGroup workerGroup;
+
+    public void start() {
+
+        bossGroup = createBossGroup();
+        workerGroup = createWorkerGroup();
+
+        serverBootstrap = new ServerBootstrap().group(bossGroup, workerGroup)
+                .channel(NioServerSocketChannel.class)
+                .option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT)
+                .option(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
+                .childOption(ChannelOption.SO_KEEPALIVE, true)
+                .childOption(ChannelOption.TCP_NODELAY, true)
+                .childOption(ChannelOption.SO_RCVBUF, 8192 * 128)
+                .childOption(ChannelOption.SO_SNDBUF, 8192 * 128)
+                .handler(new LoggingHandler(LogLevel.DEBUG))
+                .childOption(ChannelOption.ALLOCATOR, ByteBufAllocator.DEFAULT)
+                .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(
+                        8192, 31768))
+                .childHandler(new ChannelInitializer() {
+                    @Override
+                    protected void initChannel(Channel channel) throws Exception {
+                        ChannelPipeline pipeline = channel.pipeline();
+                        pipeline.addLast(new ProtocolV1Decoder(8 * 1024 * 1024));
+                        pipeline.addLast(new ProtocolV1Encoder());
+                        pipeline.addLast(new ServerChannelHandler());
+                    }
+                });
+
+        String host = "0.0.0.0";
+
+        ChannelFuture future = serverBootstrap.bind(new InetSocketAddress(host, port));
+        ChannelFuture channelFuture = future.addListener(new ChannelFutureListener() {
+
+            @Override
+            public void operationComplete(ChannelFuture future) throws Exception {
+                if (!future.isSuccess()) {
+                    throw new RuntimeException("Server start fail !", future.cause());
+                }
+            }
+        });
+
+        try {
+            channelFuture.await(5000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void stop() {
+        if (bossGroup != null) {
+            bossGroup.shutdownGracefully();
+        }
+        if (workerGroup != null) {
+            workerGroup.shutdownGracefully();
+        }
+        serverBootstrap = null;
+    }
+
+    private EventLoopGroup createBossGroup() {
+        NamedThreadFactory threadName =
+                new NamedThreadFactory("SEV-BOSS-" + port, false);
+        return new NioEventLoopGroup(2, threadName);
+    }
+
+    private EventLoopGroup createWorkerGroup() {
+        NamedThreadFactory threadName =
+                new NamedThreadFactory("SEV-WORKER-" + port, false);
+        return new NioEventLoopGroup(10, threadName);
+    }
+
+    public static void main(String[] args) {
+        ProtocolV1Server server = new ProtocolV1Server();
+        server.start();
+    }
+}
diff --git a/test/src/test/java/io/seata/core/rpc/netty/v1/ServerChannelHandler.java b/test/src/test/java/io/seata/core/rpc/netty/v1/ServerChannelHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..039e97fb566951b54b166df0cae6d212cd157742
--- /dev/null
+++ b/test/src/test/java/io/seata/core/rpc/netty/v1/ServerChannelHandler.java
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 1999-2019 Seata.io Group.
+ *
+ *  Licensed 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 io.seata.core.rpc.netty.v1;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandler;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.seata.core.protocol.ProtocolConstants;
+import io.seata.core.protocol.RpcMessage;
+
+/**
+ * @author Geng Zhang
+ */
+@ChannelHandler.Sharable
+public class ServerChannelHandler extends ChannelInboundHandlerAdapter {
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) {
+        Channel channel = ctx.channel();
+        System.out.println(msg.getClass() + "" + msg);
+
+        if (msg instanceof RpcMessage) {
+            ((RpcMessage) msg).setMessageType(ProtocolConstants.MSGTYPE_RESPONSE);
+        }
+        
+        channel.writeAndFlush(msg);
+    }
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        System.out.println(ctx.channel().remoteAddress() + " connected!");
+        ctx.fireChannelActive();
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        System.out.println(ctx.channel().remoteAddress() + " disconnected!");
+        ctx.fireChannelInactive();
+    }
+}
diff --git a/test/src/test/resources/file.conf b/test/src/test/resources/file.conf
index fa13d4c3ca7b6d8a95fd0954a75eb5376c51663e..5c0fe2f2cae60ff002c1fe8a362ea9b5c262bbf6 100644
--- a/test/src/test/resources/file.conf
+++ b/test/src/test/resources/file.conf
@@ -19,6 +19,12 @@ transport {
     #auto default pin or 8
     worker-thread-size = 8
   }
+  shutdown {
+    # when destroy server, wait seconds
+    wait = 3
+  }
+  serialization = "seata"
+  compressor = "none"
 }
 ## transaction log store
 store {
@@ -73,5 +79,5 @@ client {
 
 transaction {
   undo.data.validation = true
-  undo.log.serialization = fastjson
+  undo.log.serialization = "jackson"
 }
\ No newline at end of file