Repository: alibaba/fescar (java)

Issue:
MySQL keywords should be supported as table and field names
- [ ] I have searched the [issues](https://github.com/alibaba/fescar/issues) of this repository and believe that this is not a duplicate.

### Ⅰ. Issue Description
MySQL keywords should be supported as table and field names within the beforeImage  method of DeleteExecuter.

### Ⅱ. Describe what happened

  If there is an exception, please attach the exception trace:
if we use MySQL keyword as the filed names or table names,will cause  the following exception.

```
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'lock, id FROM work FOR UPDATE' at line 1
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
	at com.mysql.jdbc.Util.getInstance(Util.java:383)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4226)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2834)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2783)
	at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1569)
	at com.alibaba.druid.filter.FilterChainImpl.statement_executeQuery(FilterChainImpl.java:2831)
	at com.alibaba.druid.filter.FilterAdapter.statement_executeQuery(FilterAdapter.java:2503)
	at com.alibaba.druid.filter.FilterEventAdapter.statement_executeQuery(FilterEventAdapter.java:302)
	at com.alibaba.druid.filter.FilterChainImpl.statement_executeQuery(FilterChainImpl.java:2828)
	at com.alibaba.druid.proxy.jdbc.StatementProxyImpl.executeQuery(StatementProxyImpl.java:221)
	at com.alibaba.druid.pool.DruidPooledStatement.executeQuery(DruidPooledStatement.java:291)
	at com.alibaba.fescar.rm.datasource.exec.DeleteExecutor.beforeImage(DeleteExecutor.java:94)
	at com.alibaba.fescar.rm.datasource.exec.AbstractDMLBaseExecutor.executeAutoCommitFalse(AbstractDMLBaseExecutor.java:70)
	at com.alibaba.fescar.rm.datasource.exec.AbstractDMLBaseExecutor.executeAutoCommitTrue(AbstractDMLBaseExecutor.java:92)
	at com.alibaba.fescar.rm.datasource.exec.AbstractDMLBaseExecutor.doExecute(AbstractDMLBaseExecutor.java:56)
	at com.alibaba.fescar.rm.datasource.exec.BaseTransactionalExecutor.execute(BaseTransactionalExecutor.java:85)
	at com.alibaba.fescar.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:100)
	at com.alibaba.fescar.rm.datasource.exec.ExecuteTemplate.execute(ExecuteTemplate.java:46)
	at com.alibaba.fescar.rm.datasource.StatementProxy.executeUpdate(StatementProxy.java:76)
	at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:511)
	at org.springframework.jdbc.core.JdbcTemplate$1UpdateStatementCallback.doInStatement(JdbcTemplate.java:508)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:376)
	at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:523)
	at com.alibaba.fescar.samples.dubbo.service.impl.OrderServiceImpl.create(OrderServiceImpl.java:91)
	at org.apache.dubbo.common.bytecode.Wrapper2.invokeMethod(Wrapper2.java)
	at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory$1.doInvoke(JavassistProxyFactory.java:47)
	at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:86)
	at org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker.invoke(DelegateProviderMetaDataInvoker.java:56)
	at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56)
	at com.alibaba.fescar.dubbo.TransactionPropagationFilter.invoke(TransactionPropagationFilter.java:60)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:63)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:88)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:42)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:79)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:78)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:138)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:39)
	at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$1.invoke(ProtocolFilterWrapper.java:73)
	at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol$1.reply(DubboProtocol.java:108)
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:103)
	at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:200)
	at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51)
	at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
```


### Ⅲ. Describe what you expected to happen
In the above situation,There is field which called "lock",it's one of the MySQL keyword,if we use the keyword as field name or table name,then we have add  " ` " to it.otherwise,it will cause the above exceptions.


### Ⅳ. How to reproduce it (as minimally and precisely as possible)

1. xxx
2. xxx
3. xxx

### Ⅴ. Anything else we need to know?
i will fix it.

### Ⅵ. Environment:

- JDK version :
- OS :
- Others:
#485 
#459 

Pull request:
fixes #625 Optimization code of MySQL keyword checking
<!-- Please make sure you have read and understood the contributing guidelines -->

### Ⅰ. Describe what this PR did
i have tested for DeleteExecutor,InsertExecutor and UpdateExecutor,and this bug only occurs in DeleteExecutor.


### Ⅱ. Does this pull request fix one issue?
<!-- If that, add "fixes #xxx" below in the next line, for example, fixes #97. -->
fixes #625

### Ⅲ. Why don't you add test cases (unit test/integration test)? 


### Ⅳ. Describe how to verify it


### Ⅴ. Special notes for reviews



Patch:
diff --git a/common/pom.xml b/common/pom.xml
index e52065df1..4cd902ef9 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-common</artifactId>
diff --git a/config/pom.xml b/config/pom.xml
index 4eb30d859..b78dbf713 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-config</artifactId>
diff --git a/core/pom.xml b/core/pom.xml
index 7df21360f..1364cd1ad 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-core</artifactId>
diff --git a/core/src/main/java/com/alibaba/fescar/core/service/ConfigurationKeys.java b/core/src/main/java/com/alibaba/fescar/core/constants/ConfigurationKeys.java
similarity index 96%
rename from core/src/main/java/com/alibaba/fescar/core/service/ConfigurationKeys.java
rename to core/src/main/java/com/alibaba/fescar/core/constants/ConfigurationKeys.java
index 3bd67d29b..7fb884fc5 100644
--- a/core/src/main/java/com/alibaba/fescar/core/service/ConfigurationKeys.java
+++ b/core/src/main/java/com/alibaba/fescar/core/constants/ConfigurationKeys.java
@@ -14,10 +14,12 @@
  *  limitations under the License.
  */
 
-package com.alibaba.fescar.core.service;
+package com.alibaba.fescar.core.constants;
 
 /**
  * The type Configuration keys.
+ *
+ * @author jimin.jm @alibaba-inc.com
  */
 public class ConfigurationKeys {
 
diff --git a/core/src/main/java/com/alibaba/fescar/core/protocol/Version.java b/core/src/main/java/com/alibaba/fescar/core/protocol/Version.java
index 2bfc4c7d1..de6b57431 100644
--- a/core/src/main/java/com/alibaba/fescar/core/protocol/Version.java
+++ b/core/src/main/java/com/alibaba/fescar/core/protocol/Version.java
@@ -33,7 +33,7 @@ public class Version {
     /**
      * The constant CURRENT.
      */
-    public static final String CURRENT = "0.4.0";
+    public static final String CURRENT = "0.4.1";
 
     /**
      * The constant VERSION_MAP.
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/ClientType.java b/core/src/main/java/com/alibaba/fescar/core/rpc/ClientType.java
index c7de72c70..271d5e0bf 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/ClientType.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/ClientType.java
@@ -18,6 +18,8 @@ package com.alibaba.fescar.core.rpc;
 
 /**
  * The enum Client type.
+ *
+ * @author jimin.jm @alibaba-inc.com
  */
 public enum ClientType {
 
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/TransactionMessageHandler.java b/core/src/main/java/com/alibaba/fescar/core/rpc/TransactionMessageHandler.java
index aee3d18e8..3e2d2e925 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/TransactionMessageHandler.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/TransactionMessageHandler.java
@@ -21,6 +21,8 @@ import com.alibaba.fescar.core.protocol.AbstractResultMessage;
 
 /**
  * To handle the received RPC message on upper level.
+ *
+ * @author jimin.jm @alibaba-inc.com
  */
 public interface TransactionMessageHandler {
 
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/AbstractRpcRemotingClient.java b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/AbstractRpcRemotingClient.java
index ed86009b8..8682646be 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/AbstractRpcRemotingClient.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/AbstractRpcRemotingClient.java
@@ -38,8 +38,6 @@ import com.alibaba.fescar.core.rpc.ClientMessageListener;
 import com.alibaba.fescar.core.rpc.ClientMessageSender;
 import com.alibaba.fescar.core.rpc.RemotingService;
 import com.alibaba.fescar.core.rpc.netty.NettyPoolKey.TransactionRole;
-import com.alibaba.fescar.core.service.ServiceManager;
-import com.alibaba.fescar.core.service.ServiceManagerStaticConfigImpl;
 import com.alibaba.fescar.discovery.registry.RegistryFactory;
 import com.alibaba.nacos.client.naming.utils.CollectionUtils;
 
@@ -90,10 +88,6 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
     private static final int MAX_MERGE_SEND_MILLS = 1;
     private static final String THREAD_PREFIX_SPLIT_CHAR = "_";
 
-    /**
-     * The Service manager.
-     */
-    protected ServiceManager serviceManager;
 
     /**
      * The Netty client key pool.
@@ -142,7 +136,6 @@ public abstract class AbstractRpcRemotingClient extends AbstractRpcRemoting
         NettyPoolableFactory keyPoolableFactory = new NettyPoolableFactory(this);
         nettyClientKeyPool = new GenericKeyedObjectPool(keyPoolableFactory);
         nettyClientKeyPool.setConfig(getNettyPoolConfig());
-        serviceManager = new ServiceManagerStaticConfigImpl();
         super.init();
     }
 
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/NettyClientConfig.java b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/NettyClientConfig.java
index 70714e0bd..1c3cf2518 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/NettyClientConfig.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/NettyClientConfig.java
@@ -22,6 +22,8 @@ import io.netty.channel.Channel;
 
 /**
  * The type Netty client config.
+ *
+ * @author jimin.jm @alibaba-inc.com
  */
 public class NettyClientConfig extends NettyBaseConfig {
 
diff --git a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/TmRpcClient.java b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/TmRpcClient.java
index 610582fed..852dafcc5 100644
--- a/core/src/main/java/com/alibaba/fescar/core/rpc/netty/TmRpcClient.java
+++ b/core/src/main/java/com/alibaba/fescar/core/rpc/netty/TmRpcClient.java
@@ -35,6 +35,7 @@ import com.alibaba.fescar.common.thread.RejectedPolicies;
 import com.alibaba.fescar.common.util.NetUtil;
 import com.alibaba.fescar.config.Configuration;
 import com.alibaba.fescar.config.ConfigurationFactory;
+import com.alibaba.fescar.core.constants.ConfigurationKeys;
 import com.alibaba.fescar.core.context.RootContext;
 import com.alibaba.fescar.core.protocol.AbstractMessage;
 import com.alibaba.fescar.core.protocol.HeartbeatMessage;
@@ -43,7 +44,6 @@ import com.alibaba.fescar.core.protocol.RegisterTMResponse;
 import com.alibaba.fescar.core.protocol.ResultCode;
 import com.alibaba.fescar.core.protocol.transaction.GlobalBeginResponse;
 import com.alibaba.fescar.core.rpc.netty.NettyPoolKey.TransactionRole;
-import com.alibaba.fescar.core.service.ConfigurationKeys;
 import com.alibaba.fescar.discovery.loadbalance.LoadBalanceFactory;
 import com.alibaba.fescar.discovery.registry.RegistryFactory;
 import com.alibaba.nacos.client.naming.utils.CollectionUtils;
diff --git a/core/src/main/java/com/alibaba/fescar/core/service/AddressWatcher.java b/core/src/main/java/com/alibaba/fescar/core/service/AddressWatcher.java
deleted file mode 100644
index 245ceb3d9..000000000
--- a/core/src/main/java/com/alibaba/fescar/core/service/AddressWatcher.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- *  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 com.alibaba.fescar.core.service;
-
-/**
- * Watch for server address list change
- */
-public interface AddressWatcher {
-
-    /**
-     * On change.
-     *
-     * @param serverAddressArray the server address array
-     */
-    void onChange(String[] serverAddressArray);
-}
diff --git a/core/src/main/java/com/alibaba/fescar/core/service/ServiceManager.java b/core/src/main/java/com/alibaba/fescar/core/service/ServiceManager.java
deleted file mode 100644
index ef316ccca..000000000
--- a/core/src/main/java/com/alibaba/fescar/core/service/ServiceManager.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- *  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 com.alibaba.fescar.core.service;
-
-/**
- * Service Registry and Discovery
- */
-public interface ServiceManager {
-
-    /**
-     * Register address to txServiceGroup server list.
-     *
-     * @param txServiceGroup transaction service group (service name)
-     * @param address        server node address
-     */
-    void register(String txServiceGroup, String address);
-
-    /**
-     * Unregister address to txServiceGroup server list.
-     *
-     * @param txServiceGroup transaction service group (service name)
-     * @param address        server node address
-     */
-    void unregister(String txServiceGroup, String address);
-
-    /**
-     * Watch service addresses for the give txServiceGroup
-     *
-     * @param txServiceGroup transaction service group (service name)
-     * @param watcher        service address watcher
-     */
-    void watch(String txServiceGroup, AddressWatcher watcher);
-
-    /**
-     * Lookup server addresses for the given txServiceGroup
-     *
-     * @param txServiceGroup transaction service group (service name)
-     * @return available addresses
-     */
-    String[] lookup(String txServiceGroup);
-}
diff --git a/core/src/main/java/com/alibaba/fescar/core/service/ServiceManagerStaticConfigImpl.java b/core/src/main/java/com/alibaba/fescar/core/service/ServiceManagerStaticConfigImpl.java
deleted file mode 100644
index 45b638152..000000000
--- a/core/src/main/java/com/alibaba/fescar/core/service/ServiceManagerStaticConfigImpl.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Copyright 1999-2018 Alibaba Group Holding Ltd.
- *
- *  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 com.alibaba.fescar.core.service;
-
-import com.alibaba.fescar.common.exception.FrameworkException;
-import com.alibaba.fescar.common.exception.NotSupportYetException;
-import com.alibaba.fescar.common.util.StringUtils;
-import com.alibaba.fescar.config.Configuration;
-import com.alibaba.fescar.config.ConfigurationFactory;
-
-import static com.alibaba.fescar.common.exception.FrameworkErrorCode.InvalidConfiguration;
-import static com.alibaba.fescar.core.service.ConfigurationKeys.SERVER_NODE_SPLIT_CHAR;
-
-/**
- * The type Service manager static config.
- */
-public class ServiceManagerStaticConfigImpl implements ServiceManager {
-
-    private Configuration configuration = ConfigurationFactory.getInstance();
-
-    @Override
-    public void register(String txServiceGroup, String address) {
-        throw new NotSupportYetException("Dynamic registry");
-
-    }
-
-    @Override
-    public void unregister(String txServiceGroup, String address) {
-        throw new NotSupportYetException("Dynamic un-registry");
-
-    }
-
-    @Override
-    public void watch(String txServiceGroup, AddressWatcher watcher) {
-        throw new NotSupportYetException("Watch");
-
-    }
-
-    private String[] serverAddresses = null;
-
-    @Override
-    public String[] lookup(String txServiceGroup) {
-        if (serverAddresses != null) {
-            return serverAddresses;
-        }
-        String rGroup = configuration.getConfig(ConfigurationKeys.SERVICE_GROUP_MAPPING_PREFIX + txServiceGroup);
-        if (rGroup == null) {
-            throw new FrameworkException(InvalidConfiguration);
-        }
-        String rGroupDataId = ConfigurationKeys.SERVICE_PREFIX + rGroup + ConfigurationKeys.GROUPLIST_POSTFIX;
-        String serverListConfig = configuration.getConfig(rGroupDataId);
-        if (StringUtils.isNullOrEmpty(serverListConfig)) {
-            throw new FrameworkException(InvalidConfiguration);
-        }
-        serverAddresses = serverListConfig.split(SERVER_NODE_SPLIT_CHAR);
-        if (serverAddresses == null || serverAddresses.length == 0) {
-            throw new FrameworkException(InvalidConfiguration);
-        }
-        return serverAddresses;
-
-    }
-}
diff --git a/discovery/pom.xml b/discovery/pom.xml
index 9ea479fe0..81903069d 100644
--- a/discovery/pom.xml
+++ b/discovery/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/distribution/pom.xml b/distribution/pom.xml
index 81871b68b..9c6759877 100644
--- a/distribution/pom.xml
+++ b/distribution/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-distribution</artifactId>
diff --git a/dubbo-alibaba/pom.xml b/dubbo-alibaba/pom.xml
index 8ac707e85..c15ec241f 100644
--- a/dubbo-alibaba/pom.xml
+++ b/dubbo-alibaba/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/dubbo/pom.xml b/dubbo/pom.xml
index 921877457..e5299e739 100644
--- a/dubbo/pom.xml
+++ b/dubbo/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-dubbo</artifactId>
diff --git a/pom.xml b/pom.xml
index 0306ee1a6..1c2a01e30 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
 
     <groupId>com.alibaba.fescar</groupId>
     <artifactId>fescar-all</artifactId>
-    <version>0.4.0-SNAPSHOT</version>
+    <version>0.4.1-SNAPSHOT</version>
     <modules>
         <module>config</module>
         <module>common</module>
diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml
index 1ea79b790..017756a63 100644
--- a/rm-datasource/pom.xml
+++ b/rm-datasource/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-rm-datasource</artifactId>
diff --git a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/AsyncWorker.java b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/AsyncWorker.java
index d94e77285..00702a8c5 100644
--- a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/AsyncWorker.java
+++ b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/AsyncWorker.java
@@ -40,7 +40,7 @@ import com.alibaba.fescar.rm.datasource.undo.UndoLogManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.alibaba.fescar.core.service.ConfigurationKeys.CLIENT_ASYNC_COMMIT_BUFFER_LIMIT;
+import static com.alibaba.fescar.core.constants.ConfigurationKeys.CLIENT_ASYNC_COMMIT_BUFFER_LIMIT;
 
 /**
  * The type Async worker.
diff --git a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/DeleteExecutor.java b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/DeleteExecutor.java
index 99eeba870..fbbce1244 100644
--- a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/DeleteExecutor.java
+++ b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/DeleteExecutor.java
@@ -23,6 +23,7 @@ import java.sql.Statement;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.alibaba.druid.util.JdbcConstants;
 import com.alibaba.fescar.rm.datasource.ParametersHolder;
 import com.alibaba.fescar.rm.datasource.StatementProxy;
 import com.alibaba.fescar.rm.datasource.sql.SQLDeleteRecognizer;
@@ -30,6 +31,8 @@ import com.alibaba.fescar.rm.datasource.sql.SQLRecognizer;
 import com.alibaba.fescar.rm.datasource.sql.struct.TableMeta;
 import com.alibaba.fescar.rm.datasource.sql.struct.TableRecords;
 
+import com.alibaba.fescar.rm.datasource.undo.KeywordChecker;
+import com.alibaba.fescar.rm.datasource.undo.KeywordCheckerFactory;
 import org.apache.commons.lang.StringUtils;
 
 /**
@@ -54,12 +57,13 @@ public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
 
     @Override
     protected TableRecords beforeImage() throws SQLException {
-        SQLDeleteRecognizer visitor = (SQLDeleteRecognizer)sqlRecognizer;
+        SQLDeleteRecognizer visitor = (SQLDeleteRecognizer) sqlRecognizer;
+        KeywordChecker keywordChecker = KeywordCheckerFactory.getKeywordChecker(JdbcConstants.MYSQL);
 
         TableMeta tmeta = getTableMeta(visitor.getTableName());
         List<String> columns = new ArrayList<>();
         for (String column : tmeta.getAllColumns().keySet()) {
-            columns.add(column);
+            columns.add(keywordChecker.checkAndReplace(column));
         }
 
         StringBuffer selectSQLAppender = new StringBuffer("SELECT ");
@@ -73,11 +77,11 @@ public class DeleteExecutor<T, S extends Statement> extends AbstractDMLBaseExecu
         String whereCondition = null;
         ArrayList<Object> paramAppender = new ArrayList<>();
         if (statementProxy instanceof ParametersHolder) {
-            whereCondition = visitor.getWhereCondition((ParametersHolder)statementProxy, paramAppender);
+            whereCondition = visitor.getWhereCondition((ParametersHolder) statementProxy, paramAppender);
         } else {
             whereCondition = visitor.getWhereCondition();
         }
-        selectSQLAppender.append(" FROM " + getFromTableInSQL());
+        selectSQLAppender.append(" FROM " + keywordChecker.checkAndReplace(getFromTableInSQL()));
         if (StringUtils.isNotBlank(whereCondition)) {
             selectSQLAppender.append(" WHERE " + whereCondition);
         }
diff --git a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/LockRetryController.java b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/LockRetryController.java
index cd08d11fc..6dbc6bbfe 100644
--- a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/LockRetryController.java
+++ b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/exec/LockRetryController.java
@@ -17,7 +17,7 @@
 package com.alibaba.fescar.rm.datasource.exec;
 
 import com.alibaba.fescar.config.ConfigurationFactory;
-import com.alibaba.fescar.core.service.ConfigurationKeys;
+import com.alibaba.fescar.core.constants.ConfigurationKeys;
 
 /**
  * The type Lock retry controller.
diff --git a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/undo/mysql/keyword/MySQLKeywordChecker.java b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/undo/mysql/keyword/MySQLKeywordChecker.java
index 63ca8db2d..727d84600 100644
--- a/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/undo/mysql/keyword/MySQLKeywordChecker.java
+++ b/rm-datasource/src/main/java/com/alibaba/fescar/rm/datasource/undo/mysql/keyword/MySQLKeywordChecker.java
@@ -18,18 +18,22 @@ package com.alibaba.fescar.rm.datasource.undo.mysql.keyword;
 
 import com.alibaba.fescar.rm.datasource.undo.KeywordChecker;
 
-import org.apache.commons.lang3.StringUtils;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * The type My sql keyword checker.
  *
- * @author Wu
- * @date 2019 /3/5 MySQL keyword checker
+ * @author xingfudeshi@gmail.com
+ * @date 2019/3/5 MySQL keyword checker
  */
 public class MySQLKeywordChecker implements KeywordChecker {
-    private static volatile KeywordChecker keywordChecker;
+    private static volatile KeywordChecker keywordChecker = null;
+    private static volatile Set<String> keywordSet = null;
 
-    private MySQLKeywordChecker() {}
+    private MySQLKeywordChecker() {
+    }
 
     /**
      * get instance of type MySQL keyword checker
@@ -41,6 +45,7 @@ public class MySQLKeywordChecker implements KeywordChecker {
             synchronized (MySQLKeywordChecker.class) {
                 if (keywordChecker == null) {
                     keywordChecker = new MySQLKeywordChecker();
+                    keywordSet = Arrays.stream(MySQLKeyword.values()).map(MySQLKeyword::name).collect(Collectors.toSet());
                 }
             }
         }
@@ -524,30 +529,27 @@ public class MySQLKeywordChecker implements KeywordChecker {
          */
         public final String name;
 
-        MySQLKeyword() {
-            this(null);
-        }
-
         MySQLKeyword(String name) {
             this.name = name;
         }
     }
 
+
     @Override
     public boolean check(String fieldOrTableName) {
-        try {
-            if (StringUtils.isNotBlank(fieldOrTableName)) {
-                MySQLKeyword.valueOf(fieldOrTableName.toUpperCase());
-                return true;
-            }
-        } catch (IllegalArgumentException e) {
-            //do nothing
+        if (keywordSet.contains(fieldOrTableName)) {
+            return true;
+        }
+        if (null != fieldOrTableName) {
+            fieldOrTableName = fieldOrTableName.toUpperCase();
         }
-        return false;
+        return keywordSet.contains(fieldOrTableName);
+
     }
 
     @Override
     public String checkAndReplace(String fieldOrTableName) {
         return check(fieldOrTableName) ? "`" + fieldOrTableName + "`" : fieldOrTableName;
     }
+
 }
diff --git a/rm/pom.xml b/rm/pom.xml
index 16df92a63..e478e7d56 100644
--- a/rm/pom.xml
+++ b/rm/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-rm</artifactId>
diff --git a/server/pom.xml b/server/pom.xml
index d7e5c2572..ef18a791d 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-server</artifactId>
diff --git a/server/src/main/java/com/alibaba/fescar/server/session/FileBasedSessionManager.java b/server/src/main/java/com/alibaba/fescar/server/session/FileBasedSessionManager.java
index 76eea6b46..b7f31825f 100644
--- a/server/src/main/java/com/alibaba/fescar/server/session/FileBasedSessionManager.java
+++ b/server/src/main/java/com/alibaba/fescar/server/session/FileBasedSessionManager.java
@@ -24,8 +24,8 @@ import java.util.Map;
 
 import com.alibaba.fescar.common.exception.ShouldNeverHappenException;
 import com.alibaba.fescar.config.ConfigurationFactory;
+import com.alibaba.fescar.core.constants.ConfigurationKeys;
 import com.alibaba.fescar.core.model.GlobalStatus;
-import com.alibaba.fescar.core.service.ConfigurationKeys;
 import com.alibaba.fescar.server.store.FileTransactionStoreManager;
 import com.alibaba.fescar.server.store.SessionStorable;
 import com.alibaba.fescar.server.store.TransactionStoreManager;
diff --git a/spring/pom.xml b/spring/pom.xml
index de91707a2..85102a852 100644
--- a/spring/pom.xml
+++ b/spring/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-spring</artifactId>
diff --git a/tcc/pom.xml b/tcc/pom.xml
index 886f35964..b71b78604 100644
--- a/tcc/pom.xml
+++ b/tcc/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-tcc</artifactId>
diff --git a/tm/pom.xml b/tm/pom.xml
index bd13d8902..2cdbc8472 100644
--- a/tm/pom.xml
+++ b/tm/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-tm</artifactId>


Test patch:
diff --git a/config/src/test/java/com/alibaba/fescar/config/ConfigFutureTest.java b/config/src/test/java/com/alibaba/fescar/config/ConfigFutureTest.java
new file mode 100644
index 000000000..f70a9ff8f
--- /dev/null
+++ b/config/src/test/java/com/alibaba/fescar/config/ConfigFutureTest.java
@@ -0,0 +1,128 @@
+/*
+ *  Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ *  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 com.alibaba.fescar.config;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * @author mawerss1@gmail.com
+ * @date 2019/03/7
+ */
+public class ConfigFutureTest {
+
+    private static final String DATA_ID = "dataId";
+    private static final String CONTENT = "content";
+    private static final String RESULT = "result";
+
+    private static final long TIME_MILLS = 10L;
+    private static final ConfigFuture.ConfigOperation GET_OPERATION = ConfigFuture.ConfigOperation.GET;
+
+    private ConfigFuture configFuture;
+
+    @Before
+    public void initConfigFutureBeforeTest() {
+        configFuture = new ConfigFuture(DATA_ID, CONTENT, GET_OPERATION, TIME_MILLS);
+    }
+
+    /**
+     * Test get with get operation.
+     */
+    @Test
+    public void testConfigGetWithGetOperation() {
+        // return content value when future not set result
+        Assert.assertEquals(CONTENT, configFuture.get());
+        configFuture.setResult(RESULT);
+        Assert.assertEquals(RESULT, configFuture.get());
+    }
+
+    /**
+     * Test get with timeout argument
+     */
+    @Test
+    public void testConfigGetCustomeOutTime() {
+        Assert.assertEquals(CONTENT, configFuture.get(10L, TimeUnit.MILLISECONDS));
+        configFuture.setResult(RESULT);
+        Assert.assertEquals(RESULT, configFuture.get());
+    }
+
+    /**
+     * Test get with put operation.
+     */
+    @Test
+    public void testConfigGetWithPutOperation() {
+        configFuture.setOperation(ConfigFuture.ConfigOperation.PUT);
+        Assert.assertEquals(false, configFuture.get());
+        configFuture.setResult(RESULT);
+        Assert.assertEquals(RESULT, configFuture.get());
+    }
+
+    @Test
+    public void testSetContent() {
+        configFuture.setContent(CONTENT);
+        Assert.assertEquals(CONTENT, configFuture.getContent());
+    }
+
+    @Test
+    public void testGetContent() {
+        configFuture.setContent(CONTENT);
+        Assert.assertEquals(CONTENT, configFuture.getContent());
+    }
+
+    @Test
+    public void testSetDataId() {
+        configFuture.setDataId(DATA_ID);
+        Assert.assertEquals(DATA_ID, configFuture.getDataId());
+    }
+
+    @Test
+    public void testGetDataId() {
+        configFuture.setDataId(DATA_ID);
+        Assert.assertEquals(DATA_ID, configFuture.getDataId());
+    }
+
+    @Test
+    public void testSetResult() {
+        configFuture.setResult(RESULT);
+        Assert.assertEquals(RESULT, configFuture.get());
+    }
+
+    @Test
+    public void testGetOperation() {
+        configFuture.setOperation(ConfigFuture.ConfigOperation.GET);
+        Assert.assertEquals(ConfigFuture.ConfigOperation.GET, configFuture.getOperation());
+    }
+
+    @Test
+    public void testSetOperation() {
+        configFuture.setOperation(ConfigFuture.ConfigOperation.GET);
+        Assert.assertEquals(ConfigFuture.ConfigOperation.GET, configFuture.getOperation());
+    }
+
+    @Test
+    public void testIsTimeout() {
+        Assert.assertFalse(configFuture.isTimeout());
+        //TIME_MILLS + 1 ensure timeout occur
+        configFuture.get(TIME_MILLS + 1, TimeUnit.MILLISECONDS);
+        Assert.assertTrue(configFuture.isTimeout());
+    }
+
+}
diff --git a/test/pom.xml b/test/pom.xml
index 05ee4978b..560fc470f 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -20,7 +20,7 @@
     <parent>
         <artifactId>fescar-all</artifactId>
         <groupId>com.alibaba.fescar</groupId>
-        <version>0.4.0-SNAPSHOT</version>
+        <version>0.4.1-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>fescar-test</artifactId>