diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstSerializerFactory.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstSerializerFactory.java
index 987d2b1f03358634a41eff1f6f8bfe6cfc9810e1..5006ec1cca5072afa8bd240800c2cd4a01130fbf 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstSerializerFactory.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstSerializerFactory.java
@@ -19,6 +19,7 @@ import java.sql.Timestamp;
 import javax.sql.rowset.serial.SerialBlob;
 import javax.sql.rowset.serial.SerialClob;
 import org.nustaq.serialization.FSTConfiguration;
+import org.nustaq.serialization.FSTObjectSerializer;
 
 /**
  * @author funkye
@@ -39,6 +40,10 @@ public class FstSerializerFactory {
         UndoLogSerializerClassRegistry.getRegisteredClasses().keySet().forEach(conf::registerClass);
     }
 
+    public void registerSerializer(Class type, FSTObjectSerializer ser, boolean alsoForAllSubclasses) {
+        conf.registerSerializer(type, ser, alsoForAllSubclasses);
+    }
+
     public <T> byte[] serialize(T t) {
         return conf.asByteArray(t);
     }
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstUndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstUndoLogParser.java
index 146c6724d6b81f27066264e237cebb9fc00f1cdb..0231db22100f3803fab85574771ad8f389a531b0 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstUndoLogParser.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/FstUndoLogParser.java
@@ -15,21 +15,55 @@
  */
 package io.seata.rm.datasource.undo.parser;
 
+import io.seata.common.executor.Initialize;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.loader.EnhancedServiceNotFoundException;
 import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.CollectionUtils;
 import io.seata.rm.datasource.undo.BranchUndoLog;
 import io.seata.rm.datasource.undo.UndoLogParser;
+import io.seata.rm.datasource.undo.parser.spi.FstSerializer;
+import org.nustaq.serialization.FSTObjectSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
 
 /**
  * fst serializer
  * @author funkye
  */
 @LoadLevel(name = FstUndoLogParser.NAME)
-public class FstUndoLogParser implements UndoLogParser {
+public class FstUndoLogParser implements UndoLogParser, Initialize {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(FstUndoLogParser.class);
 
     public static final String NAME = "fst";
 
     private FstSerializerFactory fstFactory = FstSerializerFactory.getDefaultFactory();
 
+    @Override
+    public void init() {
+        try {
+            List<FstSerializer> serializers = EnhancedServiceLoader.loadAll(FstSerializer.class);
+            if (CollectionUtils.isNotEmpty(serializers)) {
+                for (FstSerializer serializer : serializers) {
+                    if (serializer != null) {
+                        Class type = serializer.type();
+                        FSTObjectSerializer ser = serializer.ser();
+                        boolean alsoForAllSubclasses = serializer.alsoForAllSubclasses();
+                        if (type != null && ser != null) {
+                            fstFactory.registerSerializer(type, ser, alsoForAllSubclasses);
+                            LOGGER.info("fst undo log parser load [{}].", serializer.getClass().getName());
+                        }
+                    }
+                }
+            }
+        } catch (EnhancedServiceNotFoundException e) {
+            LOGGER.warn("FstSerializer not found children class.", e);
+        }
+    }
+
     @Override
     public String getName() {
         return NAME;
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
index 6bf6cd07a78645405a7d4f4d3d5e3e96941d139b..95111267c9b2e7b4a3880f35bb150d2b9a1d3577 100644
--- 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
@@ -19,6 +19,7 @@ import java.util.Arrays;
 import java.io.IOException;
 import java.sql.SQLException;
 import java.sql.Timestamp;
+import java.util.List;
 import javax.sql.rowset.serial.SerialBlob;
 import javax.sql.rowset.serial.SerialClob;
 import javax.sql.rowset.serial.SerialException;
@@ -43,9 +44,13 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.ser.std.ArraySerializerBase;
 import io.seata.common.Constants;
 import io.seata.common.executor.Initialize;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.loader.EnhancedServiceNotFoundException;
 import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.CollectionUtils;
 import io.seata.rm.datasource.undo.BranchUndoLog;
 import io.seata.rm.datasource.undo.UndoLogParser;
+import io.seata.rm.datasource.undo.parser.spi.JacksonSerializer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -97,6 +102,28 @@ public class JacksonUndoLogParser implements UndoLogParser, Initialize {
 
     @Override
     public void init() {
+        try {
+            List<JacksonSerializer> jacksonSerializers = EnhancedServiceLoader.loadAll(JacksonSerializer.class);
+            if (CollectionUtils.isNotEmpty(jacksonSerializers)) {
+                for (JacksonSerializer jacksonSerializer : jacksonSerializers) {
+                    Class type = jacksonSerializer.type();
+                    JsonSerializer ser = jacksonSerializer.ser();
+                    JsonDeserializer deser = jacksonSerializer.deser();
+                    if (type != null) {
+                        if (ser != null) {
+                            module.addSerializer(type, ser);
+                        }
+                        if (deser != null) {
+                            module.addDeserializer(type, deser);
+                        }
+                        LOGGER.info("jackson undo log parser load [{}].", jacksonSerializer.getClass().getName());
+                    }
+                }
+            }
+        } catch (EnhancedServiceNotFoundException e) {
+            LOGGER.warn("JacksonSerializer not found children class.", e);
+        }
+
         module.addSerializer(Timestamp.class, timestampSerializer);
         module.addDeserializer(Timestamp.class, timestampDeserializer);
         module.addSerializer(SerialBlob.class, blobSerializer);
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoSerializerFactory.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoSerializerFactory.java
index fd1d66820fa7b7ed2847af43459a5a69d41bc9e3..6b566928a6237cd7b64f2d52d961701970165590 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoSerializerFactory.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoSerializerFactory.java
@@ -20,6 +20,8 @@ import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.SQLException;
 import java.sql.Timestamp;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.sql.rowset.serial.SerialBlob;
 import javax.sql.rowset.serial.SerialClob;
 import com.esotericsoftware.kryo.Kryo;
@@ -43,6 +45,8 @@ public class KryoSerializerFactory implements KryoFactory {
 
     private KryoPool pool = new KryoPool.Builder(this).softReferences().build();
 
+    private static final Map<Class, Serializer> TYPE_MAP = new ConcurrentHashMap<>();
+
     private KryoSerializerFactory() {}
 
     public static KryoSerializerFactory getInstance() {
@@ -60,11 +64,21 @@ public class KryoSerializerFactory implements KryoFactory {
         pool.release(kryoSerializer.getKryo());
     }
 
+    public void registerSerializer(Class type, Serializer ser) {
+        if (type != null && ser != null) {
+            TYPE_MAP.put(type, ser);
+        }
+    }
+
     @Override
     public Kryo create() {
         Kryo kryo = new Kryo();
         kryo.setRegistrationRequired(false);
 
+        for (Map.Entry<Class, Serializer> entry : TYPE_MAP.entrySet()) {
+            kryo.register(entry.getKey(), entry.getValue());
+        }
+
         // support clob and blob
         kryo.register(SerialBlob.class, new BlobSerializer());
         kryo.register(SerialClob.class, new ClobSerializer());
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoUndoLogParser.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoUndoLogParser.java
index c794573d8fcf715f6962debc11b86b54c23431c8..2ab834eef8dbcfd6978e2554a56daf1c97a2ed48 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoUndoLogParser.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/KryoUndoLogParser.java
@@ -15,19 +15,52 @@
  */
 package io.seata.rm.datasource.undo.parser;
 
+import com.esotericsoftware.kryo.Serializer;
+import io.seata.common.executor.Initialize;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.loader.EnhancedServiceNotFoundException;
 import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.CollectionUtils;
 import io.seata.rm.datasource.undo.BranchUndoLog;
 import io.seata.rm.datasource.undo.UndoLogParser;
+import io.seata.rm.datasource.undo.parser.spi.KryoTypeSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
 
 /**
  * kryo serializer
  * @author jsbxyyx
  */
 @LoadLevel(name = KryoUndoLogParser.NAME)
-public class KryoUndoLogParser implements UndoLogParser {
+public class KryoUndoLogParser implements UndoLogParser, Initialize {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(KryoUndoLogParser.class);
 
     public static final String NAME = "kryo";
 
+    @Override
+    public void init() {
+        try {
+            List<KryoTypeSerializer> serializers = EnhancedServiceLoader.loadAll(KryoTypeSerializer.class);
+            if (CollectionUtils.isNotEmpty(serializers)) {
+                for (KryoTypeSerializer typeSerializer : serializers) {
+                    if (typeSerializer != null) {
+                        Class type = typeSerializer.type();
+                        Serializer ser = typeSerializer.serializer();
+                        if (type != null) {
+                            KryoSerializerFactory.getInstance().registerSerializer(type, ser);
+                            LOGGER.info("kryo undo log parser load [{}].", typeSerializer.getClass().getName());
+                        }
+                    }
+                }
+            }
+        } catch (EnhancedServiceNotFoundException e) {
+            LOGGER.warn("KryoTypeSerializer not found children class.", e);
+        }
+    }
+
     @Override
     public String getName() {
         return NAME;
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
index 9f1a8cdda8aeca378bcbbe6dbc78159b0e7daaf7..6df392f67118cac3b6cef3034e447eff1f924879 100644
--- 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
@@ -18,6 +18,7 @@ package io.seata.rm.datasource.undo.parser;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.sql.Timestamp;
+import java.util.List;
 
 import io.protostuff.Input;
 import io.protostuff.LinkedBuffer;
@@ -31,9 +32,15 @@ import io.protostuff.runtime.Delegate;
 import io.protostuff.runtime.RuntimeEnv;
 import io.protostuff.runtime.RuntimeSchema;
 import io.seata.common.executor.Initialize;
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.common.loader.EnhancedServiceNotFoundException;
 import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.CollectionUtils;
 import io.seata.rm.datasource.undo.BranchUndoLog;
 import io.seata.rm.datasource.undo.UndoLogParser;
+import io.seata.rm.datasource.undo.parser.spi.ProtostuffDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The type protostuff based undo log parser.
@@ -43,6 +50,8 @@ import io.seata.rm.datasource.undo.UndoLogParser;
 @LoadLevel(name = ProtostuffUndoLogParser.NAME)
 public class ProtostuffUndoLogParser implements UndoLogParser, Initialize {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProtostuffUndoLogParser.class);
+
     public static final String NAME = "protostuff";
 
     private final DefaultIdStrategy idStrategy = (DefaultIdStrategy) RuntimeEnv.ID_STRATEGY;
@@ -51,6 +60,18 @@ public class ProtostuffUndoLogParser implements UndoLogParser, Initialize {
 
     @Override
     public void init() {
+        try {
+            List<ProtostuffDelegate> delegates = EnhancedServiceLoader.loadAll(ProtostuffDelegate.class);
+            if (CollectionUtils.isNotEmpty(delegates)) {
+                for (ProtostuffDelegate delegate : delegates) {
+                    idStrategy.registerDelegate(delegate.create());
+                    LOGGER.info("protostuff undo log parser load [{}].", delegate.getClass().getName());
+                }
+            }
+        } catch (EnhancedServiceNotFoundException e) {
+            LOGGER.warn("ProtostuffDelegate not found children class.", e);
+        }
+
         idStrategy.registerDelegate(new DateDelegate());
         idStrategy.registerDelegate(new TimestampDelegate());
         idStrategy.registerDelegate(new SqlDateDelegate());
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/FstSerializer.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/FstSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..88fd697c75654ff0892d8bf4fd93d7b2567262f4
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/FstSerializer.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.rm.datasource.undo.parser.spi;
+
+import org.nustaq.serialization.FSTObjectSerializer;
+
+/**
+ * @author jsbxyyx
+ */
+public interface FstSerializer {
+
+    /**
+     * fst serializer class type
+     * @return
+     */
+    Class type();
+
+    /**
+     * FSTObjectSerializer custom serializer
+     * @return
+     */
+    FSTObjectSerializer ser();
+
+    /**
+     * for sub classes
+     * @return
+     */
+    boolean alsoForAllSubclasses();
+
+}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/JacksonSerializer.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/JacksonSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfefa812f240734f12f482fce91f5941b324a6a1
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/JacksonSerializer.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.rm.datasource.undo.parser.spi;
+
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+
+/**
+ * @author jsbxyyx
+ */
+public interface JacksonSerializer<T> {
+
+    /**
+     * jackson serializer class type.
+     * @return
+     */
+    Class<T> type();
+
+    /**
+     * Jackson custom serializer
+     * @return
+     */
+    JsonSerializer<T> ser();
+
+    /**
+     * Jackson custom deserializer
+     * @return
+     */
+    JsonDeserializer<? extends T> deser();
+
+}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/KryoTypeSerializer.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/KryoTypeSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..54542359176db4720a49bda80fefdb56ec1b09ed
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/KryoTypeSerializer.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.rm.datasource.undo.parser.spi;
+
+import com.esotericsoftware.kryo.Serializer;
+
+/**
+ * @author jsbxyyx
+ */
+public interface KryoTypeSerializer<T> {
+
+    /**
+     * kryo serializer class type.
+     * @return
+     */
+    Class<T> type();
+
+    /**
+     * kryo custom serializer.
+     * @return
+     */
+    Serializer serializer();
+
+}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/ProtostuffDelegate.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/ProtostuffDelegate.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ec9683985af36e0c7c089a01d32826b41d22614
--- /dev/null
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/parser/spi/ProtostuffDelegate.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.spi;
+
+import io.protostuff.runtime.Delegate;
+
+/**
+ * @author jsbxyyx
+ */
+public interface ProtostuffDelegate<T> {
+
+    /**
+     * Delegate create.
+     * @return
+     */
+    Delegate<T> create();
+
+}
diff --git a/seata-plugin/pom.xml b/seata-plugin/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dd7ba7be2ab0babbeae666a826b64490fe301082
--- /dev/null
+++ b/seata-plugin/pom.xml
@@ -0,0 +1,152 @@
+<?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">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>io.seata</groupId>
+    <artifactId>seata-plugin</artifactId>
+    <version>${revision}</version>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>seata-jackson-parser-oracle</module>
+    </modules>
+
+    <properties>
+        <!-- seata plugin version -->
+        <revision>1.5.0-SNAPSHOT</revision>
+
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+        <maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
+        <maven-source-plugin.version>2.2.1</maven-source-plugin.version>
+        <maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
+
+        <ojdbc.version>19.3.0.0</ojdbc.version>
+        <seata.version>1.5.0-SNAPSHOT</seata.version>
+
+        <junit-jupiter.version>5.4.2</junit-jupiter.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>
+    </properties>
+
+    <!--test-->
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <version>${junit-jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <version>${junit-jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <version>${junit-platform-launcher.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <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>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj-core.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>com.oracle.ojdbc</groupId>
+                <artifactId>ojdbc8</artifactId>
+                <version>${ojdbc.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>io.seata</groupId>
+                <artifactId>seata-rm-datasource</artifactId>
+                <version>${seata.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven-compiler-plugin.version}</version>
+                <configuration>
+                    <source>${maven.compiler.source}</source>
+                    <target>${maven.compiler.target}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${maven-surefire-plugin.version}</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <version>${maven-source-plugin.version}</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jar-no-fork</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>ICM</id>
+            <url>http://maven.icm.edu.pl/artifactory/repo/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+
+</project>
diff --git a/seata-plugin/seata-jackson-parser-oracle/pom.xml b/seata-plugin/seata-jackson-parser-oracle/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93c6f0395a7b55aa3a9dba2b0d7aea43d42c83e5
--- /dev/null
+++ b/seata-plugin/seata-jackson-parser-oracle/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>
+        <artifactId>seata-plugin</artifactId>
+        <groupId>io.seata</groupId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>seata-jackson-parser-oracle</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.seata</groupId>
+            <artifactId>seata-rm-datasource</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.oracle.ojdbc</groupId>
+            <artifactId>ojdbc8</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/seata-plugin/seata-jackson-parser-oracle/src/main/java/io.seata.plugin.jackson.parser.oracle/OracleTimestampJacksonSerializer.java b/seata-plugin/seata-jackson-parser-oracle/src/main/java/io.seata.plugin.jackson.parser.oracle/OracleTimestampJacksonSerializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..a583a50eb27add54e509f2949c87a20a5c1a12ab
--- /dev/null
+++ b/seata-plugin/seata-jackson-parser-oracle/src/main/java/io.seata.plugin.jackson.parser.oracle/OracleTimestampJacksonSerializer.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.plugin.jackson.parser.oracle;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.JsonToken;
+import com.fasterxml.jackson.core.type.WritableTypeId;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
+import io.seata.common.loader.LoadLevel;
+import io.seata.rm.datasource.undo.parser.spi.JacksonSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * @author jsbxyyx
+ */
+@LoadLevel(name = "oracleTimestamp")
+public class OracleTimestampJacksonSerializer implements JacksonSerializer<oracle.sql.TIMESTAMP> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(OracleTimestampJacksonSerializer.class);
+
+    @Override
+    public Class<oracle.sql.TIMESTAMP> type() {
+        return oracle.sql.TIMESTAMP.class;
+    }
+
+    @Override
+    public JsonSerializer<oracle.sql.TIMESTAMP> ser() {
+        return new JsonSerializer<oracle.sql.TIMESTAMP>() {
+            @Override
+            public void serializeWithType(oracle.sql.TIMESTAMP timestamp, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSerializer) throws IOException {
+                WritableTypeId typeId = typeSerializer.writeTypePrefix(gen, typeSerializer.typeId(timestamp, JsonToken.VALUE_EMBEDDED_OBJECT));
+                serialize(timestamp, gen, serializers);
+                gen.writeTypeSuffix(typeId);
+            }
+
+            @Override
+            public void serialize(oracle.sql.TIMESTAMP timestamp, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+                try {
+                    gen.writeBinary(timestamp.getBytes());
+                } catch (IOException e) {
+                    LOGGER.error("serialize oralce.sql.Timestamp error : {}", e.getMessage(), e);
+                }
+            }
+        };
+    }
+
+    @Override
+    public JsonDeserializer<? extends oracle.sql.TIMESTAMP> deser() {
+        return new JsonDeserializer<oracle.sql.TIMESTAMP>() {
+            @Override
+            public oracle.sql.TIMESTAMP deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
+                try {
+                    oracle.sql.TIMESTAMP timestamp = new oracle.sql.TIMESTAMP(p.getBinaryValue());
+                    return timestamp;
+                } catch (IOException e) {
+                    LOGGER.error("deserialize oracle.sql.Timestamp error : {}", e.getMessage(), e);
+                }
+                return null;
+            }
+        };
+    }
+
+}
diff --git a/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.parser.spi.JacksonSerializer b/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.parser.spi.JacksonSerializer
new file mode 100644
index 0000000000000000000000000000000000000000..581b57e403ca50777c44e740c0125b2332e18877
--- /dev/null
+++ b/seata-plugin/seata-jackson-parser-oracle/src/main/resources/META-INF/services/io.seata.rm.datasource.undo.parser.spi.JacksonSerializer
@@ -0,0 +1,17 @@
+#
+#  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.
+#
+
+io.seata.plugin.jackson.parser.oracle.OracleTimestampJacksonSerializer
\ No newline at end of file
diff --git a/seata-plugin/seata-jackson-parser-oracle/src/test/java/io/seata/plugin/jackson/parser/oracle/OracleTimestampJacksonSerializerTest.java b/seata-plugin/seata-jackson-parser-oracle/src/test/java/io/seata/plugin/jackson/parser/oracle/OracleTimestampJacksonSerializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c1d7942efa680b02bde21dac925dc241e03f925
--- /dev/null
+++ b/seata-plugin/seata-jackson-parser-oracle/src/test/java/io/seata/plugin/jackson/parser/oracle/OracleTimestampJacksonSerializerTest.java
@@ -0,0 +1,29 @@
+package io.seata.plugin.jackson.parser.oracle;
+
+import io.seata.common.loader.EnhancedServiceLoader;
+import io.seata.rm.datasource.undo.parser.spi.JacksonSerializer;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+/**
+ * @author jsbxyyx
+ */
+public class OracleTimestampJacksonSerializerTest {
+
+    @Test
+    public void test_oracleJacksonSerializer() throws Exception {
+        List<JacksonSerializer> serializers = EnhancedServiceLoader.loadAll(JacksonSerializer.class);
+        Assertions.assertTrue(serializers.size() > 0, "Jackson Serializer is empty");
+        OracleTimestampJacksonSerializer s = null;
+        for (JacksonSerializer serializer : serializers) {
+            if (serializer instanceof OracleTimestampJacksonSerializer) {
+                s = (OracleTimestampJacksonSerializer) serializer;
+                break;
+            }
+        }
+        Assertions.assertNotNull(s);
+    }
+
+}