From 7ca3332d67c2f0d43ce7d854e6bbb04e48bcae8b Mon Sep 17 00:00:00 2001
From: zhangthen <45684527+zhangthen@users.noreply.github.com>
Date: Fri, 24 May 2019 17:47:44 +0800
Subject: [PATCH 1/5] Release 0.6.0 (#1106)
---
.gitignore | 3 +-
README.md | 2 +-
all/pom.xml | 30 +-
bom/pom.xml | 27 +-
.../main/java/io/seata/common/Constants.java | 11 +
.../common/loader/EnhancedServiceLoader.java | 80 ++-
.../io/seata/common/loader/LoadLevel.java | 2 +-
.../java/io/seata/common/util/BlobUtils.java | 46 +-
.../io/seata/common/util/CollectionUtils.java | 44 ++
.../io/seata/common/util/DurationUtil.java | 74 ++
.../io/seata/common/util/StringUtils.java | 118 ++--
.../io/seata/common/util/BlobUtilsTest.java | 35 +-
.../io/seata/common/util/StringUtilsTest.java | 56 +-
config/pom.xml | 1 +
config/seata-config-all/pom.xml | 5 +
.../seata/config/AbstractConfiguration.java | 21 +
.../main/java/io/seata/config/ConfigType.java | 6 +-
.../java/io/seata/config/Configuration.java | 28 +
.../io/seata/config/ConfigurationFactory.java | 22 +-
.../src/main/resources/file.conf | 6 +-
.../src/main/resources/registry.conf | 5 +-
config/seata-config-etcd3/pom.xml | 49 ++
.../seata/config/etcd/EtcdConfiguration.java | 318 +++++++++
.../etcd/EtcdConfigurationProvider.java | 32 +
.../io.seata.config.ConfigurationProvider | 1 +
core/pom.xml | 11 +
.../core/constants/ConfigurationKeys.java | 107 +++
.../java/io/seata/core/constants/DBType.java | 93 +++
.../exception/AbstractExceptionHandler.java | 7 +
.../io/seata/core/lock/AbstractLocker.java | 85 +++
.../io/seata/core/lock/LocalDBLocker.java | 42 ++
.../java/io/seata/core/lock/LockMode.java | 37 +
.../main/java/io/seata/core/lock/Locker.java | 59 ++
.../main/java/io/seata/core/lock/RowLock.java | 193 +++++
.../seata/core/protocol/AbstractMessage.java | 3 +-
.../java/io/seata/core/protocol/Version.java | 2 +-
.../io/seata/core/rpc/ChannelManager.java | 1 -
.../java/io/seata/core/rpc/RpcContext.java | 1 -
.../core/rpc/netty/AbstractRpcRemoting.java | 5 -
.../core/rpc/netty/NettyClientConfig.java | 2 -
.../core/rpc/netty/NettyPoolableFactory.java | 1 -
.../rpc/netty/RegisterCheckAuthHandler.java | 2 -
.../core/rpc/netty/RegisterMsgListener.java | 2 -
.../seata/core/store/BranchTransactionDO.java | 277 ++++++++
.../seata/core/store/GlobalTransactionDO.java | 256 +++++++
.../main/java/io/seata/core/store/LockDO.java | 178 +++++
.../java/io/seata/core/store/LockStore.java | 68 ++
.../java/io/seata/core/store/LogStore.java | 110 +++
.../store/db/AbstractDataSourceGenerator.java | 148 ++++
.../core/store/db/DataSourceGenerator.java | 35 +
.../core/store/db/LockStoreDataBaseDAO.java | 356 ++++++++++
.../io/seata/core/store/db/LockStoreSqls.java | 143 ++++
.../core/store/db/LogStoreDataBaseDAO.java | 533 ++++++++++++++
.../io/seata/core/store/db/LogStoreSqls.java | 323 +++++++++
.../services/io.seata.core.store.LockStore | 1 +
.../services/io.seata.core.store.LogStore | 1 +
.../core/protocol/RegisterTMRequestTest.java | 192 +++++
.../store/db/DataBaseLockStoreDAOTest.java | 300 ++++++++
.../store/db/LogStoreDataBaseDAOTest.java | 659 ++++++++++++++++++
.../config/ConfigurationFactoryTest.java | 32 +
.../eureka/EurekaRegistryProvider.java | 1 -
.../registry/nacos/NacosRegistryProvider.java | 1 -
.../registry/redis/RedisRegistryProvider.java | 2 -
.../redis/RedisRegistryServiceImpl.java | 1 -
pom.xml | 4 +-
rm-datasource/pom.xml | 11 +
.../AbstractPreparedStatementProxy.java | 1 -
.../io/seata/rm/datasource/AsyncWorker.java | 4 +-
.../rm/datasource/PreparedStatementProxy.java | 2 -
.../seata/rm/datasource/StatementProxy.java | 2 -
.../rm/datasource/exec/DeleteExecutor.java | 2 -
.../rm/datasource/sql/WhereRecognizer.java | 1 -
.../datasource/undo/AbstractUndoExecutor.java | 162 ++++-
.../rm/datasource/undo/UndoLogManager.java | 15 +-
.../undo/AbstractUndoExecutorTest.java | 316 +++++++++
.../rm/datasource/undo/UndoExecutorTest.java | 40 +-
.../datasource/undo/UndoLogManagerTest.java | 16 +-
.../keyword/MySQLKeywordCheckerTest.java | 1 -
server/pom.xml | 18 +
.../server/AbstractTCInboundHandler.java | 7 +-
.../src/main/java/io/seata/server/Server.java | 2 +-
.../coordinator/DefaultCoordinator.java | 215 ++++--
.../seata/server/coordinator/DefaultCore.java | 39 +-
.../server/lock/AbstractLockManager.java | 117 ++++
.../seata/server/lock/DefaultLockManager.java | 103 +++
.../server/lock/DefaultLockManagerImpl.java | 186 -----
.../io/seata/server/lock/LockManager.java | 23 +-
.../io/seata/server/lock/LockerFactory.java | 99 +++
.../seata/server/lock/db/DataBaseLocker.java | 101 +++
.../server/lock/memory/MemoryLocker.java | 193 +++++
.../session/AbstractSessionManager.java | 64 +-
.../seata/server/session/BranchSession.java | 84 ++-
.../server/session/DefaultSessionManager.java | 59 +-
.../seata/server/session/GlobalSession.java | 120 +++-
.../server/session/SessionCondition.java | 82 ++-
.../seata/server/session/SessionHelper.java | 1 +
.../seata/server/session/SessionHolder.java | 35 +-
.../seata/server/session/SessionManager.java | 5 +-
.../session/db/DataBaseSessionManager.java | 186 +++++
.../{ => file}/FileBasedSessionManager.java | 82 ++-
.../AbstractTransactionStoreManager.java | 44 ++
.../ReloadableStore.java} | 36 +-
.../server/store/TransactionStoreManager.java | 26 +-
.../db/DatabaseTransactionStoreManager.java | 299 ++++++++
.../store/db/DbcpDataSourceGenerator.java | 54 ++
.../store/db/DruidDataSourceGenerator.java | 54 ++
.../FileTransactionStoreManager.java | 60 +-
.../services/io.seata.core.lock.Locker | 2 +
...io.seata.core.store.db.DataSourceGenerator | 2 +
.../io.seata.server.session.SessionManager | 3 +
...seata.server.store.TransactionStoreManager | 2 +
server/src/main/resources/db_store.sql | 52 ++
server/src/main/resources/file.conf | 47 +-
server/src/main/resources/logback.xml | 2 +-
server/src/main/resources/nacos-config.txt | 24 +-
server/src/main/resources/registry.conf | 5 +-
.../test/java/WriteStoreMultithreadTest.java | 5 +-
server/src/test/java/WriteStoreTest.java | 14 +-
.../coordinator/DefaultCoordinatorTest.java | 23 +-
.../server/coordinator/DefaultCoreTest.java | 42 +-
.../io/seata/server/lock/LockManagerTest.java | 11 +-
.../lock/db/DataBaseLockManagerImplTest.java | 301 ++++++++
.../lock/memory/MemoryLockManagerForTest.java | 32 +
.../MemoryLockManagerImplTest.java} | 14 +-
.../session/DefaultSessionManagerTest.java | 11 +-
.../session/FileBasedSessionManagerTest.java | 21 +-
.../db/DataBaseSessionManagerTest.java | 565 +++++++++++++++
.../seata/server/store/SessionStoreTest.java | 108 +--
.../java/io/seata/rm/tcc/TwoPhaseResult.java | 3 -
.../seata/rm/tcc/remoting/RemotingParser.java | 2 -
.../parser/LocalTCCRemotingParser.java | 1 -
.../parser/SofaRpcRemotingParser.java | 2 -
.../seata/core/rpc/netty/TmRpcClientTest.java | 3 -
test/src/test/resources/file.conf | 4 +
test/src/test/resources/registry.conf | 7 +-
.../io/seata/tm/TransactionManagerHolder.java | 6 -
.../tm/api/DefaultGlobalTransaction.java | 1 -
137 files changed, 8733 insertions(+), 845 deletions(-)
create mode 100644 common/src/main/java/io/seata/common/util/DurationUtil.java
create mode 100644 config/seata-config-etcd3/pom.xml
create mode 100644 config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java
create mode 100644 config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.java
create mode 100644 config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
create mode 100644 core/src/main/java/io/seata/core/constants/DBType.java
create mode 100644 core/src/main/java/io/seata/core/lock/AbstractLocker.java
create mode 100644 core/src/main/java/io/seata/core/lock/LocalDBLocker.java
create mode 100644 core/src/main/java/io/seata/core/lock/LockMode.java
create mode 100644 core/src/main/java/io/seata/core/lock/Locker.java
create mode 100644 core/src/main/java/io/seata/core/lock/RowLock.java
create mode 100644 core/src/main/java/io/seata/core/store/BranchTransactionDO.java
create mode 100644 core/src/main/java/io/seata/core/store/GlobalTransactionDO.java
create mode 100644 core/src/main/java/io/seata/core/store/LockDO.java
create mode 100644 core/src/main/java/io/seata/core/store/LockStore.java
create mode 100644 core/src/main/java/io/seata/core/store/LogStore.java
create mode 100644 core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java
create mode 100644 core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java
create mode 100644 core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
create mode 100644 core/src/main/java/io/seata/core/store/db/LockStoreSqls.java
create mode 100644 core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java
create mode 100644 core/src/main/java/io/seata/core/store/db/LogStoreSqls.java
create mode 100644 core/src/main/resources/META-INF/services/io.seata.core.store.LockStore
create mode 100644 core/src/main/resources/META-INF/services/io.seata.core.store.LogStore
create mode 100644 core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
create mode 100644 core/src/test/java/io/seata/core/store/db/DataBaseLockStoreDAOTest.java
create mode 100644 core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java
create mode 100644 discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java
create mode 100644 rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
create mode 100644 server/src/main/java/io/seata/server/lock/AbstractLockManager.java
create mode 100644 server/src/main/java/io/seata/server/lock/DefaultLockManager.java
delete mode 100644 server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java
create mode 100644 server/src/main/java/io/seata/server/lock/LockerFactory.java
create mode 100644 server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java
create mode 100644 server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java
create mode 100644 server/src/main/java/io/seata/server/session/db/DataBaseSessionManager.java
rename server/src/main/java/io/seata/server/session/{ => file}/FileBasedSessionManager.java (71%)
create mode 100644 server/src/main/java/io/seata/server/store/AbstractTransactionStoreManager.java
rename server/src/main/java/io/seata/server/{lock/LockManagerFactory.java => store/ReloadableStore.java} (54%)
create mode 100644 server/src/main/java/io/seata/server/store/db/DatabaseTransactionStoreManager.java
create mode 100644 server/src/main/java/io/seata/server/store/db/DbcpDataSourceGenerator.java
create mode 100644 server/src/main/java/io/seata/server/store/db/DruidDataSourceGenerator.java
rename server/src/main/java/io/seata/server/store/{ => file}/FileTransactionStoreManager.java (92%)
create mode 100644 server/src/main/resources/META-INF/services/io.seata.core.lock.Locker
create mode 100644 server/src/main/resources/META-INF/services/io.seata.core.store.db.DataSourceGenerator
create mode 100644 server/src/main/resources/META-INF/services/io.seata.server.session.SessionManager
create mode 100644 server/src/main/resources/META-INF/services/io.seata.server.store.TransactionStoreManager
create mode 100644 server/src/main/resources/db_store.sql
create mode 100644 server/src/test/java/io/seata/server/lock/db/DataBaseLockManagerImplTest.java
create mode 100644 server/src/test/java/io/seata/server/lock/memory/MemoryLockManagerForTest.java
rename server/src/test/java/io/seata/server/lock/{DefaultLockManagerImplTest.java => memory/MemoryLockManagerImplTest.java} (87%)
create mode 100644 server/src/test/java/io/seata/server/session/db/DataBaseSessionManagerTest.java
diff --git a/.gitignore b/.gitignore
index e34b7b267cd..44b06f93f74 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ target/
*.tar.gz
*.class
.flattened-pom.xml
+dependency-reduced-pom.xml
# eclipse ignore
.settings/
@@ -36,4 +37,4 @@ target/
# system ignore
.DS_Store
Thumbs.db
-*.orig
\ No newline at end of file
+*.orig
diff --git a/README.md b/README.md
index a4676b789b6..766f5739690 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
-0.5.1
+0.5.2
io.seata
diff --git a/all/pom.xml b/all/pom.xml
index 8f092f4971d..e05b28dcc51 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -21,7 +21,7 @@
io.seata
seata-all
- 0.5.2
+ 0.6.0
Seata All-in-one ${project.version}
http://seata.io
@@ -112,6 +112,11 @@
seata-config-consul
${project.version}
+
+ io.seata
+ seata-config-etcd3
+ ${project.version}
+
io.seata
seata-core
@@ -423,7 +428,7 @@
true
false
false
- false
+ true
io.seata:seata-common
@@ -433,6 +438,7 @@
io.seata:seata-config-nacos
io.seata:seata-config-zk
io.seata:seata-config-consul
+ io.seata:seata-config-etcd3
io.seata:seata-discovery-core
io.seata:seata-discovery-consul
io.seata:seata-discovery-eureka
@@ -473,6 +479,12 @@
registry.conf
+
+ *:*
+
+ META-INF/maven/**
+
+
@@ -497,20 +509,12 @@
maven-javadoc-plugin
2.10.4
- ${project.build.sourceEncoding}
- true
- true
- false
- true
- true
- true
-
- io.seata:seata-*
-
+ ${project.build.sourceEncoding}
+ false
- attach-javadocs
+ package
jar
diff --git a/bom/pom.xml b/bom/pom.xml
index dc5ca5ed57d..76b370961a0 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -20,7 +20,7 @@
io.seata
seata-bom
- 0.5.2
+ 0.6.0
4.0.0
pom
@@ -30,29 +30,28 @@
4.3.23.RELEASE
4.1.24.Final
- 4.12
2.7.0
2.6.5
5.5.3
- 1.2.48
+ 1.2.58
1.2.1
1.7.22
1.2.0
2.6
2.4.2
1.6
+ 1.3
3.1
1.0
0.10
2.9.1
1.0.2
- 6.4
0.8.3
1.1.0
2.9.0
1.9.5
1.4.2
- 0.9.1
+ 1.0.0
0.3.0
1.11.2
27.0.1-jre
@@ -63,6 +62,9 @@
4.4.11
1.1.12
2.7.0
+ 10.2.0.3.0
+ 5.1.30
+ 1.4.181
@@ -270,6 +272,21 @@
caffeine
${caffeine.version}
+
+ commons-dbcp
+ commons-dbcp
+ ${commons-dbcp.version}
+
+
+ com.h2database
+ h2
+ ${h2.version}
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.client.version}
+
diff --git a/common/src/main/java/io/seata/common/Constants.java b/common/src/main/java/io/seata/common/Constants.java
index a76bacb155d..e39d856f5b9 100644
--- a/common/src/main/java/io/seata/common/Constants.java
+++ b/common/src/main/java/io/seata/common/Constants.java
@@ -15,6 +15,8 @@
*/
package io.seata.common;
+import java.nio.charset.Charset;
+
/**
* The type Constants.
*
@@ -97,4 +99,13 @@ public class Constants {
*/
public final static String TCC_ACTION_CONTEXT = "actionContext";
+ /**
+ * default charset name
+ */
+ public static final String DEFAULT_CHARSET_NAME = "UTF-8";
+
+ /**
+ * default charset is utf-8
+ */
+ public static final Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME);
}
diff --git a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
index d10d95999bc..4c80b9c59f3 100644
--- a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
+++ b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
@@ -18,6 +18,8 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
@@ -27,6 +29,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import io.seata.common.Constants;
import io.seata.common.executor.Initialize;
import io.seata.common.util.CollectionUtils;
@@ -102,12 +105,48 @@ public static S load(Class service, String activateName, ClassLoader load
return loadFile(service, activateName, loader);
}
+ /**
+ * Load s.
+ *
+ * @param the type parameter
+ * @param service the service
+ * @param activateName the activate name
+ * @param args the args
+ * @return the s
+ * @throws EnhancedServiceNotFoundException the enhanced service not found exception
+ */
+ public static S load(Class service, String activateName, Object[] args) throws EnhancedServiceNotFoundException {
+ Class[] argsType = null;
+ if(args != null && args.length > 0){
+ argsType = new Class[args.length];
+ for(int i = 0; i < args.length; i ++){
+ argsType[i] = args[i].getClass();
+ }
+ }
+ return loadFile(service, activateName, findClassLoader(), argsType, args);
+ }
+
+ /**
+ * Load s.
+ *
+ * @param the type parameter
+ * @param service the service
+ * @param activateName the activate name
+ * @param argsType the args type
+ * @param args the args
+ * @return the s
+ * @throws EnhancedServiceNotFoundException the enhanced service not found exception
+ */
+ public static S load(Class service, String activateName, Class[] argsType, Object[] args) throws EnhancedServiceNotFoundException {
+ return loadFile(service, activateName, findClassLoader(), argsType, args);
+ }
+
/**
* get all implements
*
* @param the type parameter
* @param service the service
- * @return list
+ * @return list list
*/
public static List loadAll(Class service) {
List allInstances = new ArrayList<>();
@@ -117,7 +156,7 @@ public static List loadAll(Class service) {
}
try {
for (Class clazz : allClazzs) {
- allInstances.add(initInstance(service, clazz));
+ allInstances.add(initInstance(service, clazz, null, null));
}
} catch (Throwable t) {
throw new EnhancedServiceNotFoundException(t);
@@ -150,8 +189,12 @@ public static List getAllExtensionClass(Class service, ClassLoader
return findAllExtensionClass(service, null, loader);
}
- @SuppressWarnings("rawtypes")
private static S loadFile(Class service, String activateName, ClassLoader loader) {
+ return loadFile(service, activateName, loader, null, null);
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static S loadFile(Class service, String activateName, ClassLoader loader, Class[] argTypes, Object[] args) {
try {
boolean foundFromCache = true;
List extensions = providers.get(service);
@@ -173,7 +216,7 @@ private static S loadFile(Class service, String activateName, ClassLoader
Class clz = extensions.get(i);
@SuppressWarnings("unchecked")
LoadLevel activate = (LoadLevel)clz.getAnnotation(LoadLevel.class);
- if (activate != null && activateName.equals(activate.name())) {
+ if (activate != null && activateName.equalsIgnoreCase(activate.name())) {
activateExtensions.add(clz);
}
}
@@ -187,7 +230,7 @@ private static S loadFile(Class service, String activateName, ClassLoader
+ "] and classloader : " + ObjectUtils.toString(loader));
}
Class> extension = extensions.get(extensions.size() - 1);
- S result = initInstance(service, extension);
+ S result = initInstance(service, extension, argTypes, args);
if (!foundFromCache && LOGGER.isInfoEnabled()) {
LOGGER.info("load " + service.getSimpleName() + "[" + activateName + "] extension by class[" + extension
.getName() + "]");
@@ -259,7 +302,7 @@ private static void loadFile(Class> service, String dir, ClassLoader classLoad
java.net.URL url = urls.nextElement();
BufferedReader reader = null;
try {
- reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
+ reader = new BufferedReader(new InputStreamReader(url.openStream(), Constants.DEFAULT_CHARSET));
String line = null;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
@@ -292,13 +335,26 @@ private static void loadFile(Class> service, String dir, ClassLoader classLoad
* @param the type parameter
* @param service the service
* @param implClazz the impl clazz
- * @return s
- * @throws IllegalAccessException the illegal access exception
- * @throws InstantiationException the instantiation exception
+ * @param argTypes the arg types
+ * @param args the args
+ * @return s s
+ * @throws IllegalAccessException the illegal access exception
+ * @throws InstantiationException the instantiation exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws InvocationTargetException the invocation target exception
*/
- protected static S initInstance(Class service, Class implClazz)
- throws IllegalAccessException, InstantiationException {
- S s = service.cast(implClazz.newInstance());
+ protected static S initInstance(Class service, Class implClazz, Class[] argTypes, Object[] args)
+ throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
+ S s = null;
+ if(argTypes != null && args != null){
+ // Constructor with arguments
+ Constructor constructor = implClazz.getDeclaredConstructor(argTypes);
+ constructor.setAccessible(true);
+ s = service.cast(constructor.newInstance(args));
+ }else {
+ // default Constructor
+ s = service.cast(implClazz.newInstance());
+ }
if (s instanceof Initialize) {
((Initialize)s).init();
}
diff --git a/common/src/main/java/io/seata/common/loader/LoadLevel.java b/common/src/main/java/io/seata/common/loader/LoadLevel.java
index b01ebf76c74..b887ed509b0 100644
--- a/common/src/main/java/io/seata/common/loader/LoadLevel.java
+++ b/common/src/main/java/io/seata/common/loader/LoadLevel.java
@@ -43,5 +43,5 @@
*
* @return the int
*/
- int order();
+ int order() default 0;
}
diff --git a/common/src/main/java/io/seata/common/util/BlobUtils.java b/common/src/main/java/io/seata/common/util/BlobUtils.java
index 3eb62aa0c28..60ddc7eaabc 100644
--- a/common/src/main/java/io/seata/common/util/BlobUtils.java
+++ b/common/src/main/java/io/seata/common/util/BlobUtils.java
@@ -15,19 +15,18 @@
*/
package io.seata.common.util;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
import java.sql.Blob;
import javax.sql.rowset.serial.SerialBlob;
-import io.seata.common.exception.ShouldNeverHappenException;
+import io.seata.common.Constants;
import io.seata.common.exception.ShouldNeverHappenException;
/**
* The type Blob utils.
*
* @author jimin.jm @alibaba-inc.com
+ * @author Geng Zhang
*/
public class BlobUtils {
@@ -47,7 +46,7 @@ public static Blob string2blob(String str) {
}
try {
- return new SerialBlob(str.getBytes());
+ return new SerialBlob(str.getBytes(Constants.DEFAULT_CHARSET));
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
@@ -65,26 +64,43 @@ public static String blob2string(Blob blob) {
}
try {
- return new String(blob.getBytes((long)1, (int)blob.length()));
+ return new String(blob.getBytes((long) 1, (int) blob.length()), Constants.DEFAULT_CHARSET);
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
- * Input stream 2 string string.
+ * Byte array to blob
*
- * @param is the is
- * @return the string
+ * @param bytes the byte array
+ * @return the blob
+ */
+ public static Blob bytes2Blob(byte[] bytes) {
+ if (bytes == null) {
+ return null;
+ }
+
+ try {
+ return new SerialBlob(bytes);
+ } catch (Exception e) {
+ throw new ShouldNeverHappenException(e);
+ }
+ }
+
+ /**
+ * Blob to byte array.
+ *
+ * @param blob the blob
+ * @return the byte array
*/
- public static String inputStream2String(InputStream is) {
+ public static byte[] blob2Bytes(Blob blob) {
+ if (blob == null) {
+ return null;
+ }
+
try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int i = -1;
- while ((i = is.read()) != -1) {
- baos.write(i);
- }
- return baos.toString();
+ return blob.getBytes((long) 1, (int) blob.length());
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
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 76126fc4cf4..d56b80eb1ec 100644
--- a/common/src/main/java/io/seata/common/util/CollectionUtils.java
+++ b/common/src/main/java/io/seata/common/util/CollectionUtils.java
@@ -16,6 +16,7 @@
package io.seata.common.util;
import java.util.Collection;
+import java.util.Iterator;
/**
* The type Collection utils.
@@ -45,6 +46,49 @@ public static boolean isNotEmpty(Collection col){
return col != null && col.size() > 0;
}
+ /**
+ * Is empty boolean.
+ *
+ * @param array the array
+ * @return the boolean
+ */
+ public static boolean isEmpty(Object[] array){
+ return !isNotEmpty(array);
+ }
+
+ /**
+ * Is not empty boolean.
+ *
+ * @param array the array
+ * @return the boolean
+ */
+ public static boolean isNotEmpty(Object[] array){
+ return array != null && array.length > 0;
+ }
+
+ /**
+ * To string string.
+ *
+ * @param col the col
+ * @return the string
+ */
+ public static String toString(Collection col){
+ if(isEmpty(col)){
+ return "";
+ }
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ Iterator it = col.iterator();
+ while (it.hasNext()){
+ Object obj = it.next();
+ sb.append(StringUtils.toString(obj));
+ sb.append(",");
+ }
+ sb.deleteCharAt(sb.length() - 1);
+ sb.append("]");
+ return sb.toString();
+ }
+
/**
* Is size equals boolean.
*
diff --git a/common/src/main/java/io/seata/common/util/DurationUtil.java b/common/src/main/java/io/seata/common/util/DurationUtil.java
new file mode 100644
index 00000000000..567fc85e3f5
--- /dev/null
+++ b/common/src/main/java/io/seata/common/util/DurationUtil.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.common.util;
+
+import java.time.Duration;
+
+/**
+ * @author XCXCXCXCX
+ */
+public class DurationUtil {
+
+ public static final Duration DEFAULT_DURATION = Duration.ofMillis(-1);
+
+ public static final String DAY_UNIT = "d";
+ public static final String HOUR_UNIT = "h";
+ public static final String MINIUTE_UNIT = "m";
+ public static final String SECOND_UNIT = "s";
+ public static final String MILLIS_SECOND_UNIT = "ms";
+
+ public static Duration parse(String str) {
+ if(StringUtils.isBlank(str)){
+ return DEFAULT_DURATION;
+ }
+
+ if (str.contains(MILLIS_SECOND_UNIT)) {
+ Long value = doParse(MILLIS_SECOND_UNIT, str);
+ return value == null ? null : Duration.ofMillis(value);
+ } else if (str.contains(DAY_UNIT)) {
+ Long value = doParse(DAY_UNIT, str);
+ return value == null ? null : Duration.ofDays(value);
+ } else if (str.contains(HOUR_UNIT)) {
+ Long value = doParse(HOUR_UNIT, str);
+ return value == null ? null : Duration.ofHours(value);
+ } else if (str.contains(MINIUTE_UNIT)) {
+ Long value = doParse(MINIUTE_UNIT, str);
+ return value == null ? null : Duration.ofMinutes(value);
+ } else if (str.contains(SECOND_UNIT)) {
+ Long value = doParse(SECOND_UNIT, str);
+ return value == null ? null : Duration.ofSeconds(value);
+ }
+ try {
+ int millis = Integer.parseInt(str);
+ return Duration.ofMillis(millis);
+ }catch (Exception e){
+ throw new UnsupportedOperationException(str + " can't parse to duration", e);
+ }
+ }
+
+ private static Long doParse(String unit, String str) {
+ str = str.replace(unit, "");
+ if ("".equals(str)) {
+ return null;
+ }
+ try {
+ return Long.parseLong(str);
+ } catch (NumberFormatException e) {
+ throw new UnsupportedOperationException("\"" + str + "\" can't parse to Duration", e);
+ }
+ }
+
+}
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 217538aae17..e6a1714e78b 100644
--- a/common/src/main/java/io/seata/common/util/StringUtils.java
+++ b/common/src/main/java/io/seata/common/util/StringUtils.java
@@ -15,19 +15,17 @@
*/
package io.seata.common.util;
+import io.seata.common.Constants;
+import io.seata.common.exception.ShouldNeverHappenException;
+
import java.io.ByteArrayOutputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
-import java.sql.Blob;
-import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
-import javax.sql.rowset.serial.SerialBlob;
-
/**
* The type String utils.
*
@@ -37,7 +35,6 @@
public class StringUtils {
private StringUtils() {
-
}
/**
@@ -54,7 +51,7 @@ public static boolean isNullOrEmpty(String str) {
* Is blank string ?
*
* @param str the str
- * @return boolean
+ * @return boolean boolean
*/
public static boolean isBlank(String str) {
int length;
@@ -74,7 +71,7 @@ public static boolean isBlank(String str) {
* Is Not blank string ?
*
* @param str the str
- * @return boolean
+ * @return boolean boolean
*/
public static boolean isNotBlank(String str) {
int length;
@@ -91,56 +88,83 @@ public static boolean isNotBlank(String str) {
return false;
}
+ /**
+ * Equals boolean.
+ *
+ * @param a the a
+ * @param b the b
+ * @return boolean
+ */
+ public static boolean equals(String a, String b) {
+ if (a == null) {
+ return b == null;
+ }
+ return a.equals(b);
+ }
+
/**
- * String 2 blob blob.
+ * Equals ignore case boolean.
*
- * @param str the str
- * @return the blob
- * @throws SQLException the sql exception
+ * @param a the a
+ * @param b the b
+ * @return the boolean
*/
- public static Blob string2blob(String str) throws SQLException {
- if (str == null) {
- return null;
+ public static boolean equalsIgnoreCase(String a, String b) {
+ if (a == null) {
+ return b == null;
}
- return new SerialBlob(str.getBytes());
+ return a.equalsIgnoreCase(b);
}
/**
- * Blob 2 string string.
+ * Input stream 2 string string.
*
- * @param blob the blob
+ * @param is the is
* @return the string
- * @throws SQLException the sql exception
*/
- public static String blob2string(Blob blob) throws SQLException {
- if (blob == null) {
+ public static String inputStream2String(InputStream is) {
+ if (is == null) {
return null;
}
-
- return new String(blob.getBytes((long)1, (int)blob.length()));
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int i = -1;
+ while ((i = is.read()) != -1) {
+ baos.write(i);
+ }
+ return baos.toString(Constants.DEFAULT_CHARSET_NAME);
+ } catch (Exception e) {
+ throw new ShouldNeverHappenException(e);
+ }
}
/**
- * Input stream 2 string string.
+ * Input stream to byte array
*
* @param is the is
- * @return the string
- * @throws IOException the io exception
+ * @return the byte array
*/
- public static String inputStream2String(InputStream is) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int i = -1;
- while ((i = is.read()) != -1) {
- baos.write(i);
+ public static byte[] inputStream2Bytes(InputStream is) {
+ if (is == null) {
+ return null;
+ }
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int i = -1;
+ while ((i = is.read()) != -1) {
+ baos.write(i);
+ }
+ return baos.toByteArray();
+ } catch (Exception e) {
+ throw new ShouldNeverHappenException(e);
}
- return baos.toString();
}
/**
* Object.toString()
*
* @param obj the obj
- * @return string
+ * @return string string
*/
public static String toString(Object obj){
if (obj == null){
@@ -197,32 +221,4 @@ public static String toString(Object obj){
}
return sb.toString();
}
-
- /**
- * Equals boolean.
- *
- * @param a the a
- * @param b the b
- * @return boolean
- */
- public static boolean equals(String a, String b) {
- if (a == null) {
- return b == null;
- }
- return a.equals(b);
- }
-
- /**
- * Equals ignore case boolean.
- *
- * @param a the a
- * @param b the b
- * @return the boolean
- */
- public static boolean equalsIgnoreCase(String a, String b) {
- if (a == null) {
- return b == null;
- }
- return a.equalsIgnoreCase(b);
- }
}
diff --git a/common/src/test/java/io/seata/common/util/BlobUtilsTest.java b/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
index 53a0a6217ae..f643ad49caa 100644
--- a/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
+++ b/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
@@ -15,21 +15,22 @@
*/
package io.seata.common.util;
-import java.io.InputStream;
-import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialBlob;
-import org.junit.jupiter.api.Disabled;
+import io.seata.common.Constants;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type Blob utils test.
*
* @author Otis.z
+ * @author Geng Zhang
* @date 2019 /2/26
*/
public class BlobUtilsTest {
@@ -41,8 +42,9 @@ public class BlobUtilsTest {
*/
@Test
public void testString2blob() throws SQLException {
+ assertNull(BlobUtils.string2blob(null));
assertThat(BlobUtils.string2blob("123abc")).isEqualTo(
- new SerialBlob("123abc".getBytes(Charset.forName("UTF-8"))));
+ new SerialBlob("123abc".getBytes(Constants.DEFAULT_CHARSET)));
}
/**
@@ -52,19 +54,24 @@ public void testString2blob() throws SQLException {
*/
@Test
public void testBlob2string() throws SQLException {
- assertThat(BlobUtils.blob2string(new SerialBlob("123absent".getBytes(Charset.forName("UTF-8"))))).isEqualTo(
+ assertNull(BlobUtils.blob2string(null));
+ assertThat(BlobUtils.blob2string(new SerialBlob("123absent".getBytes(Constants.DEFAULT_CHARSET)))).isEqualTo(
"123absent");
}
- /**
- * Test input stream 2 string.
- */
@Test
- @Disabled
- public void testInputStream2String() {
- InputStream inputStream = BlobUtilsTest.class.getClassLoader().getResourceAsStream("test.txt");
- assertThat(BlobUtils.inputStream2String(inputStream)).isEqualTo("abc\n"
- + ":\"klsdf\n"
- + "2ks,x:\".,-3sd˚ø≤ø¬≥");
+ void bytes2Blob() throws UnsupportedEncodingException, SQLException {
+ assertNull(BlobUtils.bytes2Blob(null));
+ byte[] bs = "xxa哈哈dd".getBytes(Constants.DEFAULT_CHARSET_NAME);
+ assertThat(BlobUtils.bytes2Blob(bs)).isEqualTo(
+ new SerialBlob(bs));
+ }
+
+ @Test
+ void blob2Bytes() throws UnsupportedEncodingException, SQLException {
+ assertNull(BlobUtils.blob2Bytes(null));
+ byte[] bs = "xxa哈哈dd".getBytes(Constants.DEFAULT_CHARSET_NAME);
+ assertThat(BlobUtils.blob2Bytes(new SerialBlob(bs))).isEqualTo(
+ bs);
}
}
diff --git a/common/src/test/java/io/seata/common/util/StringUtilsTest.java b/common/src/test/java/io/seata/common/util/StringUtilsTest.java
index 1eae80462bf..c816c0358cb 100644
--- a/common/src/test/java/io/seata/common/util/StringUtilsTest.java
+++ b/common/src/test/java/io/seata/common/util/StringUtilsTest.java
@@ -15,17 +15,15 @@
*/
package io.seata.common.util;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.sql.SQLException;
-
-import javax.sql.rowset.serial.SerialBlob;
+import io.seata.common.Constants;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type String utils test.
@@ -48,43 +46,25 @@ public void testIsNullOrEmpty() {
assertThat(StringUtils.isNullOrEmpty(" ")).isFalse();
}
- /**
- * Test string 2 blob.
- *
- * @throws SQLException the sql exception
- */
@Test
- public void testString2blob() throws SQLException {
- assertThat(StringUtils.string2blob(null)).isNull();
- String[] strs = new String[] {"abc", "", " "};
- for (String str : strs) {
- assertThat(StringUtils.string2blob(str)).isEqualTo(new SerialBlob(str.getBytes()));
- }
- }
-
- /**
- * Test blob 2 string.
- *
- * @throws SQLException the sql exception
- */
- @Test
- public void testBlob2string() throws SQLException {
- String[] strs = new String[] {"abc", " "};
- for (String str : strs) {
- assertThat(StringUtils.blob2string(new SerialBlob(str.getBytes()))).isEqualTo(str);
-
- }
+ public void testInputStream2String() throws IOException {
+ assertNull(StringUtils.inputStream2String(null));
+ String data = "abc\n"
+ + ":\"klsdf\n"
+ + "2ks,x:\".,-3sd˚ø≤ø¬≥";
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
+ assertThat(StringUtils.inputStream2String(inputStream)).isEqualTo(data);
}
- /**
- * Test input stream 2 string.
- */
@Test
- @Disabled
- public void testInputStream2String() throws IOException {
- InputStream inputStream = StringUtilsTest.class.getClassLoader().getResourceAsStream("test.txt");
- assertThat(StringUtils.inputStream2String(inputStream))
- .isEqualTo("abc\n" + ":\"klsdf\n" + "2ks,x:\".,-3sd˚ø≤ø¬≥");
+ void inputStream2Bytes() {
+ assertNull(StringUtils.inputStream2Bytes(null));
+ String data = "abc\n"
+ + ":\"klsdf\n"
+ + "2ks,x:\".,-3sd˚ø≤ø¬≥";
+ byte[] bs = data.getBytes(Constants.DEFAULT_CHARSET);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
+ assertThat(StringUtils.inputStream2Bytes(inputStream)).isEqualTo(bs);
}
@Test
diff --git a/config/pom.xml b/config/pom.xml
index cfdf735708d..36b384ebda6 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -32,6 +32,7 @@
seata-config-nacos
seata-config-zk
seata-config-all
+ seata-config-etcd3
seata-config-consul
diff --git a/config/seata-config-all/pom.xml b/config/seata-config-all/pom.xml
index 3cf62928e1b..46da42a13db 100644
--- a/config/seata-config-all/pom.xml
+++ b/config/seata-config-all/pom.xml
@@ -41,6 +41,11 @@
seata-config-nacos
${project.version}
+
+ ${project.groupId}
+ seata-config-etcd3
+ ${project.version}
+
${project.groupId}
seata-config-consul
diff --git a/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java b/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
index 7cd509eccdd..0092f4f36ac 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
@@ -15,6 +15,11 @@
*/
package io.seata.config;
+
+import io.seata.common.util.DurationUtil;
+
+import java.time.Duration;
+
/**
* The type Abstract configuration.
*
@@ -61,6 +66,22 @@ public long getLong(String dataId) {
return getLong(dataId, 0L);
}
+ @Override
+ public Duration getDuration(String dataId) {
+ return getDuration(dataId, Duration.ZERO);
+ }
+
+ @Override
+ public Duration getDuration(String dataId, Duration defaultValue) {
+ return getDuration(dataId, defaultValue, DEFAULT_CONFIG_TIMEOUT);
+ }
+
+ @Override
+ public Duration getDuration(String dataId, Duration defaultValue, long timeoutMills) {
+ String result = getConfig(dataId, String.valueOf(defaultValue.toMillis() + "ms"), timeoutMills);
+ return DurationUtil.parse(result);
+ }
+
@Override
public boolean getBoolean(String dataId, boolean defaultValue, long timeoutMills) {
String result = getConfig(dataId, String.valueOf(defaultValue), timeoutMills);
diff --git a/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java b/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
index 866fddb8d67..6f8cf55a4ed 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
@@ -41,7 +41,11 @@ public enum ConfigType {
/**
* Consul config type
*/
- Consul;
+ Consul,
+ /**
+ * Etcd3 config type
+ */
+ Etcd3;
/**
* Gets type.
diff --git a/config/seata-config-core/src/main/java/io/seata/config/Configuration.java b/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
index bb3e1a7c18c..67ec8679191 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
@@ -15,6 +15,7 @@
*/
package io.seata.config;
+import java.time.Duration;
import java.util.List;
/**
@@ -80,6 +81,33 @@ public interface Configuration {
*/
long getLong(String dataId);
+ /**
+ * Gets duration.
+ *
+ * @param dataId
+ * @return the duration
+ */
+ Duration getDuration(String dataId);
+
+ /**
+ * Gets duration.
+ *
+ * @param dataId
+ * @param defaultValue
+ * @return the duration
+ */
+ Duration getDuration(String dataId, Duration defaultValue);
+
+ /**
+ * Gets duration.
+ *
+ * @param dataId
+ * @param defaultValue
+ * @param timeoutMills
+ * @return he duration
+ */
+ Duration getDuration(String dataId, Duration defaultValue, long timeoutMills);
+
/**
* Gets boolean.
*
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 0b802b3d344..cd5ea345d5c 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
@@ -17,8 +17,6 @@
import io.seata.common.exception.NotSupportYetException;
import io.seata.common.loader.EnhancedServiceLoader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import java.util.Objects;
@@ -26,10 +24,9 @@
* The type Configuration factory.
*
* @author jimin.jm @alibaba-inc.com
- * @date 2018 /12/24
+ * @author Geng Zhang
*/
public final class ConfigurationFactory {
- private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationFactory.class);
private static final String REGISTRY_CONF = "registry.conf";
/**
* The constant FILE_INSTANCE.
@@ -38,20 +35,33 @@ public final class ConfigurationFactory {
private static final String NAME_KEY = "name";
private static final String FILE_TYPE = "file";
+ private static volatile Configuration CONFIG_INSTANCE = null;
+
/**
* Gets instance.
*
* @return the instance
*/
public static Configuration getInstance() {
+ if (CONFIG_INSTANCE == null) {
+ synchronized (Configuration.class) {
+ if (CONFIG_INSTANCE == null) {
+ CONFIG_INSTANCE = buildConfiguration();
+ }
+ }
+ }
+ return CONFIG_INSTANCE;
+ }
+
+ private static Configuration buildConfiguration() {
ConfigType configType = null;
String configTypeName = null;
try {
configTypeName = FILE_INSTANCE.getConfig(ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
+ ConfigurationKeys.FILE_ROOT_TYPE);
configType = ConfigType.getType(configTypeName);
- } catch (Exception exx) {
- throw new NotSupportYetException("not support register type: " + configTypeName);
+ } catch (Exception e) {
+ throw new NotSupportYetException("not support register type: " + configTypeName, e);
}
if (ConfigType.File == configType) {
String pathDataId = ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
diff --git a/config/seata-config-core/src/main/resources/file.conf b/config/seata-config-core/src/main/resources/file.conf
index dc09514d367..a166f8d5c5c 100644
--- a/config/seata-config-core/src/main/resources/file.conf
+++ b/config/seata-config-core/src/main/resources/file.conf
@@ -69,4 +69,8 @@ client {
retry.times = 30
}
report.retry.count = 5
-}
\ No newline at end of file
+}
+
+transaction {
+ undo.data.validation = true
+}
diff --git a/config/seata-config-core/src/main/resources/registry.conf b/config/seata-config-core/src/main/resources/registry.conf
index 1d6c3598256..5115876d916 100644
--- a/config/seata-config-core/src/main/resources/registry.conf
+++ b/config/seata-config-core/src/main/resources/registry.conf
@@ -45,7 +45,7 @@ registry {
}
config {
- # file、nacos 、apollo、zk、consul
+ # file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
@@ -65,6 +65,9 @@ config {
session.timeout = 6000
connect.timeout = 2000
}
+ etcd3 {
+ serverAddr = "http://localhost:2379"
+ }
file {
name = "file.conf"
}
diff --git a/config/seata-config-etcd3/pom.xml b/config/seata-config-etcd3/pom.xml
new file mode 100644
index 00000000000..beb590dfffe
--- /dev/null
+++ b/config/seata-config-etcd3/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+
+ io.seata
+ seata-config
+ ${revision}
+
+ 4.0.0
+ seata-config-etcd3
+ seata-config-etcd3 ${project.version}
+
+
+
+ io.seata
+ seata-config-core
+ ${project.parent.version}
+
+
+ io.etcd
+ jetcd-core
+
+
+ com.google.guava
+ guava
+
+
+
+
+ com.google.guava
+ guava
+
+
+
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/etcd/EtcdConfiguration.java
new file mode 100644
index 00000000000..6eed7d53035
--- /dev/null
+++ b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java
@@ -0,0 +1,318 @@
+/*
+ * 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.config.etcd;
+
+import io.etcd.jetcd.ByteSequence;
+import io.etcd.jetcd.Client;
+import io.etcd.jetcd.KeyValue;
+import io.etcd.jetcd.Watch;
+import io.etcd.jetcd.kv.DeleteResponse;
+import io.etcd.jetcd.kv.GetResponse;
+import io.etcd.jetcd.kv.PutResponse;
+import io.etcd.jetcd.kv.TxnResponse;
+import io.etcd.jetcd.op.Cmp;
+import io.etcd.jetcd.op.CmpTarget;
+import io.etcd.jetcd.op.Op;
+import io.etcd.jetcd.options.PutOption;
+import io.etcd.jetcd.watch.WatchResponse;
+import io.seata.common.exception.ShouldNeverHappenException;
+import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.util.CollectionUtils;
+import io.seata.config.AbstractConfiguration;
+import io.seata.config.ConfigChangeListener;
+import io.seata.config.ConfigFuture;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+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 static io.netty.util.CharsetUtil.UTF_8;
+import static io.seata.config.ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR;
+import static io.seata.config.ConfigurationKeys.FILE_ROOT_CONFIG;
+
+/**
+ * @author xingfudeshi@gmail.com
+ * @date 2019/05/10
+ */
+public class EtcdConfiguration extends AbstractConfiguration {
+ private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfiguration.class);
+ private static volatile EtcdConfiguration instance;
+ private static volatile Client client;
+
+ private static final Configuration FILE_CONFIG = ConfigurationFactory.FILE_INSTANCE;
+ private static final String SERVER_ADDR_KEY = "serverAddr";
+ private static final String CONFIG_TYPE = "etcd3";
+ private static final String FILE_CONFIG_KEY_PREFIX = FILE_ROOT_CONFIG + FILE_CONFIG_SPLIT_CHAR + CONFIG_TYPE + FILE_CONFIG_SPLIT_CHAR;
+ private static final int THREAD_POOL_NUM = 1;
+ private static final int MAP_INITIAL_CAPACITY = 8;
+ private static ExecutorService etcdConfigExecutor = null;
+ private static ExecutorService etcdNotifierExecutor = null;
+ private static ConcurrentMap> configListenersMap = null;
+ private static ConcurrentHashMap> configChangeNotifiersMap = null;
+
+ private static final long VERSION_NOT_EXIST = 0;
+
+ private EtcdConfiguration() {
+ }
+
+ /**
+ * get instance
+ *
+ * @return
+ */
+ public static EtcdConfiguration getInstance() {
+ if (null == instance) {
+ synchronized (EtcdConfiguration.class) {
+ if (null == instance) {
+ etcdConfigExecutor = new ThreadPoolExecutor(THREAD_POOL_NUM, THREAD_POOL_NUM,
+ Integer.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("etcd-config-executor", THREAD_POOL_NUM));
+ etcdNotifierExecutor = new ThreadPoolExecutor(THREAD_POOL_NUM, THREAD_POOL_NUM,
+ Integer.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("etcd-config-notifier-executor", THREAD_POOL_NUM));
+ configListenersMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
+ configChangeNotifiersMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
+ instance = new EtcdConfiguration();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+ @Override
+ public String getTypeName() {
+ return CONFIG_TYPE;
+ }
+
+ @Override
+ public String getConfig(String dataId, String defaultValue, long timeoutMills) {
+ ConfigFuture configFuture = new ConfigFuture(dataId, defaultValue, ConfigFuture.ConfigOperation.GET, timeoutMills);
+ etcdConfigExecutor.execute(() -> {
+ complete(getClient().getKVClient().get(ByteSequence.from(dataId, UTF_8)), configFuture);
+ });
+ return (String) configFuture.get();
+ }
+
+ @Override
+ public boolean putConfig(String dataId, String content, long timeoutMills) {
+ ConfigFuture configFuture = new ConfigFuture(dataId, content, ConfigFuture.ConfigOperation.PUT, timeoutMills);
+ etcdConfigExecutor.execute(() -> {
+ complete(getClient().getKVClient().put(ByteSequence.from(dataId, UTF_8), ByteSequence.from(content, UTF_8)), configFuture);
+ });
+ return (Boolean) configFuture.get();
+ }
+
+ @Override
+ public boolean putConfigIfAbsent(String dataId, String content, long timeoutMills) {
+ ConfigFuture configFuture = new ConfigFuture(dataId, content, ConfigFuture.ConfigOperation.PUTIFABSENT, timeoutMills);
+ etcdConfigExecutor.execute(() -> {
+ //use etcd transaction to ensure the atomic operation
+ complete(client.getKVClient().txn()
+ //whether the key exists
+ .If(new Cmp(ByteSequence.from(dataId, UTF_8), Cmp.Op.EQUAL, CmpTarget.version(VERSION_NOT_EXIST)))
+ //not exist,then will create
+ .Then(Op.put(ByteSequence.from(dataId, UTF_8), ByteSequence.from(content, UTF_8), PutOption.DEFAULT))
+ .commit(), configFuture);
+ });
+ return (Boolean) configFuture.get();
+ }
+
+ @Override
+ public boolean removeConfig(String dataId, long timeoutMills) {
+ ConfigFuture configFuture = new ConfigFuture(dataId, null, ConfigFuture.ConfigOperation.REMOVE, timeoutMills);
+ etcdConfigExecutor.execute(() -> {
+ complete(getClient().getKVClient().delete(ByteSequence.from(dataId, UTF_8)), configFuture);
+ });
+ return (Boolean) configFuture.get();
+ }
+
+ @Override
+ public void addConfigListener(String dataId, ConfigChangeListener listener) {
+ configListenersMap.putIfAbsent(dataId, new ArrayList<>());
+ configChangeNotifiersMap.putIfAbsent(dataId, new ArrayList<>());
+ ConfigChangeNotifier configChangeNotifier = new ConfigChangeNotifier(dataId, listener);
+ configChangeNotifiersMap.get(dataId).add(configChangeNotifier);
+ if (null != listener.getExecutor()) {
+ listener.getExecutor().submit(configChangeNotifier);
+ } else {
+ etcdNotifierExecutor.submit(configChangeNotifier);
+ }
+ }
+
+ @Override
+ public void removeConfigListener(String dataId, ConfigChangeListener listener) {
+ List configChangeListeners = getConfigListeners(dataId);
+ if (configChangeListeners == null) {
+ return;
+ }
+ List newChangeListenerList = new ArrayList<>();
+ for (ConfigChangeListener changeListener : configChangeListeners) {
+ if (!changeListener.equals(listener)) {
+ newChangeListenerList.add(changeListener);
+ }
+ }
+ configListenersMap.put(dataId, newChangeListenerList);
+ if (null != listener.getExecutor()) {
+ listener.getExecutor().shutdownNow();
+ }
+ //remove and stop the configChangeNotifier
+ List configChangeNotifiers = configChangeNotifiersMap.get(dataId);
+ List newConfigChangeNotifiers = new ArrayList<>();
+ for (ConfigChangeNotifier configChangeNotifier : configChangeNotifiers) {
+ if (!listener.equals(configChangeNotifier.getListener())) {
+ newConfigChangeNotifiers.add(configChangeNotifier);
+ } else {
+ configChangeNotifier.stop();
+ }
+ }
+ configChangeNotifiersMap.put(dataId, newConfigChangeNotifiers);
+ }
+
+ @Override
+ public List getConfigListeners(String dataId) {
+ return configListenersMap.get(dataId);
+ }
+
+ /**
+ * get client
+ *
+ * @return client
+ */
+ private static Client getClient() {
+ if (null == client) {
+ synchronized (EtcdConfiguration.class) {
+ if (null == client) {
+ client = Client.builder().endpoints(FILE_CONFIG.getConfig(FILE_CONFIG_KEY_PREFIX + SERVER_ADDR_KEY)).build();
+ }
+ }
+ }
+ return client;
+ }
+
+ /**
+ * complete the future
+ *
+ * @param completableFuture
+ * @param configFuture
+ * @param
+ */
+ private void complete(CompletableFuture completableFuture, ConfigFuture configFuture) {
+ try {
+ T response = completableFuture.get();
+ if (response instanceof GetResponse) {
+ List keyValues = ((GetResponse) response).getKvs();
+ if (CollectionUtils.isNotEmpty(keyValues)) {
+ ByteSequence value = keyValues.get(0).getValue();
+ if (null != value) {
+ configFuture.setResult(value.toString(UTF_8));
+ }
+ }
+ } else if (response instanceof PutResponse) {
+ configFuture.setResult(Boolean.TRUE);
+ } else if (response instanceof TxnResponse) {
+ boolean result = ((TxnResponse) response).isSucceeded();
+ //create key if file does not exist)
+ if (result) {
+ configFuture.setResult(Boolean.TRUE);
+ }
+ } else if (response instanceof DeleteResponse) {
+ configFuture.setResult(Boolean.TRUE);
+ } else {
+ throw new ShouldNeverHappenException("unsupported response type");
+ }
+ } catch (Exception e) {
+ LOGGER.error("error occurred while completing the future{}", e.getMessage());
+ }
+ }
+
+ /**
+ * the type config change notifier
+ */
+ private static class ConfigChangeNotifier implements Runnable {
+ private final String dataId;
+ private final ConfigChangeListener listener;
+ private Watch.Watcher watcher;
+
+ ConfigChangeNotifier(String dataId, ConfigChangeListener listener) {
+ this.dataId = dataId;
+ this.listener = listener;
+ }
+
+ /**
+ * get the listener
+ *
+ * @return ConfigChangeListener
+ */
+ ConfigChangeListener getListener() {
+ return this.listener;
+ }
+
+ @Override
+ public void run() {
+ Watch watchClient = getClient().getWatchClient();
+ watcher = watchClient.watch(ByteSequence.from(dataId, UTF_8), new Watch.Listener() {
+ @Override
+ public void onNext(WatchResponse response) {
+ notifyListeners();
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+
+ }
+
+ @Override
+ public void onCompleted() {
+
+ }
+ });
+ }
+
+ /**
+ * notify listeners
+ */
+ private void notifyListeners() {
+ try {
+ GetResponse getResponse = getClient().getKVClient().get(ByteSequence.from(dataId, UTF_8)).get();
+ List keyValues = getResponse.getKvs();
+ if (CollectionUtils.isNotEmpty(keyValues)) {
+ for (ConfigChangeListener listener : configListenersMap.get(this.dataId)) {
+ listener.receiveConfigInfo(keyValues.get(0).getValue().toString(UTF_8));
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("error occurred while getting value{}", e.getMessage());
+ }
+ }
+
+
+ /**
+ * stop the notifier
+ */
+ public void stop() {
+ this.watcher.close();
+ }
+ }
+}
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/etcd/EtcdConfigurationProvider.java
new file mode 100644
index 00000000000..acb7e28db96
--- /dev/null
+++ b/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.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.config.etcd;
+
+import io.seata.common.loader.LoadLevel;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationProvider;
+
+/**
+ * @author xingfudeshi@gmail.com
+ * @date 2019/04/12
+ */
+@LoadLevel(name = "Etcd3", order = 1)
+public class EtcdConfigurationProvider implements ConfigurationProvider {
+ @Override
+ public Configuration provide() {
+ return EtcdConfiguration.getInstance();
+ }
+}
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
new file mode 100644
index 00000000000..ce01ac19760
--- /dev/null
+++ b/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
@@ -0,0 +1 @@
+io.seata.config.etcd.EtcdConfigurationProvider
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index a6a71f8e60d..9670f9fd495 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -55,6 +55,17 @@
commons-pool
commons-pool
+
+ commons-dbcp
+ commons-dbcp
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
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 4df7b3f11c6..dc6f93fef8c 100644
--- a/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
+++ b/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
@@ -92,4 +92,111 @@ public class ConfigurationKeys {
* The constant CLIENT_REPORT_RETRY_COUNT.
*/
public static final String CLIENT_REPORT_RETRY_COUNT = CLIENT_PREFIX + "report.retry.count";
+
+ /**
+ * The constant STORE_DB_GLOBAL_TABLE.
+ */
+ public static final String STORE_DB_GLOBAL_TABLE = "store.db.global.table";
+
+ /**
+ * The constant STORE_DB_BRANCH_TABLE.
+ */
+ public static final String STORE_DB_BRANCH_TABLE = "store.db.branch.table";
+
+ /**
+ * The constant STORE_DB_GLOBAL_DEFAULT_TABLE.
+ */
+ public static final String STORE_DB_GLOBAL_DEFAULT_TABLE = "global_table";
+
+ /**
+ * The constant STORE_DB_BRANCH_DEFAULT_TABLE.
+ */
+ public static final String STORE_DB_BRANCH_DEFAULT_TABLE = "branch_table";
+
+ /**
+ * The constant STORE_DB_DATASOURCE_TYPE.
+ */
+ public static final String STORE_DB_DATASOURCE_TYPE = "store.db.datasource";
+
+
+ /**
+ * The constant STORE_DB_TYPE.
+ */
+ public static final String STORE_DB_TYPE = "store.db.db-type";
+
+ /**
+ * The constant STORE_DB_URL.
+ */
+ public static final String STORE_DB_URL = "store.db.url";
+
+ /**
+ * The constant STORE_DB_USER.
+ */
+ public static final String STORE_DB_USER = "store.db.user";
+
+ /**
+ * The constant STORE_DB_PASSWORD.
+ */
+ public static final String STORE_DB_PASSWORD = "store.db.password";
+
+ /**
+ * The constant STORE_DB_MIN_CONN.
+ */
+ public static final String STORE_DB_MIN_CONN = "store.db.min-conn";
+
+ /**
+ * The constant STORE_DB_MAX_CONN.
+ */
+ public static final String STORE_DB_MAX_CONN = "store.db.max-conn";
+
+ /**
+ * The constant STORE_DB_LOG_QUERY_LIMIT.
+ */
+ public static final String STORE_DB_LOG_QUERY_LIMIT = "store.db.query-limit";
+
+ /**
+ * The constant LOCK_MODE.
+ */
+ public static final String LOCK_MODE = "lock.mode";
+
+ /**
+ * The constant LOCK_DB_TABLE.
+ */
+ public static final String LOCK_DB_TABLE = "lock.db.lock-table";
+
+ /**
+ * The constant LOCK_DB_DEFAULT_TABLE.
+ */
+ public static final String LOCK_DB_DEFAULT_TABLE = "lock_table";
+
+ /**
+ * The constant COMMITING_RETRY_DELAY.
+ */
+ public static final String COMMITING_RETRY_DELAY = "recovery.committing-retry-delay";
+
+ /**
+ * The constant ASYN_COMMITING_RETRY_DELAY.
+ */
+ public static final String ASYN_COMMITING_RETRY_DELAY = "recovery.asyn-committing-retry-delay";
+
+ /**
+ * The constant ROLLBACKING_RETRY_DELAY.
+ */
+ public static final String ROLLBACKING_RETRY_DELAY = "recovery.rollbacking-retry-delay";
+
+ /**
+ * The constant TIMEOUT_RETRY_DELAY.
+ */
+ public static final String TIMEOUT_RETRY_DELAY = "recovery.timeout-retry-delay";
+
+
+ /**
+ * The constant TRANSACTION_PREFIX.
+ */
+ public static final String TRANSACTION_PREFIX = "transaction.";
+
+ /**
+ * The constant RM_DATASOURCE_UNOD_VALIDATION.
+ */
+ public static final String TRANSACTION_UNOD_DATA_VALIDATION = TRANSACTION_PREFIX + "undo.data.validation";
}
diff --git a/core/src/main/java/io/seata/core/constants/DBType.java b/core/src/main/java/io/seata/core/constants/DBType.java
new file mode 100644
index 00000000000..cdb0174b985
--- /dev/null
+++ b/core/src/main/java/io/seata/core/constants/DBType.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.core.constants;
+
+import io.seata.common.util.StringUtils;
+
+/**
+ * database type
+ *
+ * @author zhangsen
+ * @data 2019 /4/2
+ */
+public enum DBType {
+
+ /**
+ * Mysql db type.
+ */
+ MYSQL,
+
+ /**
+ * Oracle db type.
+ */
+ ORACLE,
+
+ /**
+ * Db 2 db type.
+ */
+ DB2,
+
+ /**
+ * Sqlserver db type.
+ */
+ SQLSERVER,
+
+ /**
+ * Sybaee db type.
+ */
+ SYBAEE,
+
+ /**
+ * H2 db type.
+ */
+ H2,
+
+ /**
+ * Sqlite db type.
+ */
+ SQLITE,
+
+ /**
+ * Access db type.
+ */
+ ACCESS,
+
+ /**
+ * Postgresql db type.
+ */
+ POSTGRESQL,
+
+ /**
+ * Oceanbase db type.
+ */
+ OCEANBASE;
+
+ /**
+ * Valueof db type.
+ *
+ * @param dbType the db type
+ * @return the db type
+ */
+ public static DBType valueof (String dbType){
+ for(DBType dt : values()){
+ if(StringUtils.equalsIgnoreCase(dt.name(),dbType)){
+ return dt;
+ }
+ }
+ throw new IllegalArgumentException("unknown dbtype:" + dbType);
+ }
+
+}
\ No newline at end of file
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 9aa741dd28d..a8501be705a 100644
--- a/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
+++ b/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
@@ -15,6 +15,8 @@
*/
package io.seata.core.exception;
+import io.seata.config.Configuration;
+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;
@@ -26,6 +28,11 @@
*/
public abstract class AbstractExceptionHandler {
+ /**
+ * The constant CONFIG.
+ */
+ protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
+
/**
* The interface Callback.
*
diff --git a/core/src/main/java/io/seata/core/lock/AbstractLocker.java b/core/src/main/java/io/seata/core/lock/AbstractLocker.java
new file mode 100644
index 00000000000..ddb0dd073ef
--- /dev/null
+++ b/core/src/main/java/io/seata/core/lock/AbstractLocker.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.core.lock;
+
+import io.seata.common.util.CollectionUtils;
+import io.seata.core.store.LockDO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The type Abstract locker.
+ *
+ * @author zhangsen
+ * @data 2019 -05-15
+ */
+public abstract class AbstractLocker implements Locker {
+
+ /**
+ * The constant LOGGER.
+ */
+ protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLocker.class);
+
+ /**
+ * The constant LOCK_SPLIT.
+ */
+ protected static final String LOCK_SPLIT = "^^^";
+
+ /**
+ * Convert to lock do list.
+ *
+ * @param locks the locks
+ * @return the list
+ */
+ protected List convertToLockDO(List locks){
+ List lockDOs = new ArrayList<>();
+ if(CollectionUtils.isEmpty(locks)){
+ return lockDOs;
+ }
+ for(RowLock rowLock : locks){
+ LockDO lockDO = new LockDO();
+ lockDO.setBranchId(rowLock.getBranchId());
+ lockDO.setPk(rowLock.getPk());
+ lockDO.setResourceId(rowLock.getResourceId());
+ lockDO.setRowKey(getRowKey(rowLock.getResourceId(), rowLock.getTableName(), rowLock.getPk()));
+ lockDO.setXid(rowLock.getXid());
+ lockDO.setTransactionId(rowLock.getTransactionId());
+ lockDO.setTableName(rowLock.getTableName());
+ lockDOs.add(lockDO);
+ }
+ return lockDOs;
+ }
+
+ /**
+ * Get row key string.
+ *
+ * @param resourceId the resource id
+ * @param tableName the table name
+ * @param pk the pk
+ * @return the string
+ */
+ protected String getRowKey(String resourceId, String tableName, String pk){
+ return new StringBuilder().append(resourceId).append(LOCK_SPLIT).append(tableName).append(LOCK_SPLIT).append(pk).toString();
+ }
+
+ @Override
+ public void cleanAllLocks() {
+
+ }
+}
diff --git a/core/src/main/java/io/seata/core/lock/LocalDBLocker.java b/core/src/main/java/io/seata/core/lock/LocalDBLocker.java
new file mode 100644
index 00000000000..c342e8f6ecf
--- /dev/null
+++ b/core/src/main/java/io/seata/core/lock/LocalDBLocker.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.core.lock;
+
+import java.util.List;
+
+/**
+ * The type Local db locker.
+ *
+ * @author zhangsen
+ * @data 2019 -05-15
+ */
+public class LocalDBLocker extends AbstractLocker {
+
+ @Override
+ public boolean acquireLock(List rowLock) {
+ return false;
+ }
+
+ @Override
+ public boolean releaseLock(List rowLock) {
+ return false;
+ }
+
+ @Override
+ public boolean isLockable(List rowLock) {
+ return false;
+ }
+}
diff --git a/core/src/main/java/io/seata/core/lock/LockMode.java b/core/src/main/java/io/seata/core/lock/LockMode.java
new file mode 100644
index 00000000000..f1a11d0b9ea
--- /dev/null
+++ b/core/src/main/java/io/seata/core/lock/LockMode.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.core.lock;
+
+/**
+ * lock mode
+ *
+ * @author zhangsen
+ * @data 2019 /4/25
+ */
+public enum LockMode {
+
+ /**
+ * store the lock in memory of server
+ */
+ MEMORY,
+
+ /**
+ * store the lock in db of server
+ */
+ DB;
+
+
+}
diff --git a/core/src/main/java/io/seata/core/lock/Locker.java b/core/src/main/java/io/seata/core/lock/Locker.java
new file mode 100644
index 00000000000..8990699d317
--- /dev/null
+++ b/core/src/main/java/io/seata/core/lock/Locker.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.core.lock;
+
+import java.util.List;
+
+/**
+ * The interface Locker.
+ *
+ * @author zhangsen
+ * @data 2019 -05-15
+ */
+public interface Locker {
+
+ /**
+ * Acquire lock boolean.
+ *
+ * @param rowLock the row lock
+ * @return the boolean
+ */
+ boolean acquireLock(List rowLock) ;
+
+ /**
+ * Un lock boolean.
+ *
+ * @param rowLock the row lock
+ * @return the boolean
+ */
+ boolean releaseLock(List rowLock);
+
+ /**
+ * Is lockable boolean.
+ *
+ * @param rowLock the row lock
+ * @return the boolean
+ */
+ boolean isLockable(List rowLock);
+
+ /**
+ * Clean all locks boolean.
+ *
+ * @return the boolean
+ */
+ void cleanAllLocks();
+}
+
diff --git a/core/src/main/java/io/seata/core/lock/RowLock.java b/core/src/main/java/io/seata/core/lock/RowLock.java
new file mode 100644
index 00000000000..9675cb9011d
--- /dev/null
+++ b/core/src/main/java/io/seata/core/lock/RowLock.java
@@ -0,0 +1,193 @@
+/*
+ * 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.lock;
+
+import io.seata.common.util.StringUtils;
+
+/**
+ * The type Row lock.
+ *
+ * @author zhangsen
+ * @data 2019 -05-15
+ */
+public class RowLock {
+
+ private String xid;
+
+ private Long transactionId;
+
+ private Long branchId;
+
+ private String resourceId;
+
+ private String tableName;
+
+ private String pk;
+
+ private String rowKey;
+
+ private String feature;
+
+ /**
+ * Gets xid.
+ *
+ * @return the xid
+ */
+ public String getXid() {
+ return xid;
+ }
+
+ /**
+ * Sets xid.
+ *
+ * @param xid the xid
+ */
+ public void setXid(String xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * Gets transaction id.
+ *
+ * @return the transaction id
+ */
+ public Long getTransactionId() {
+ return transactionId;
+ }
+
+ /**
+ * Sets transaction id.
+ *
+ * @param transactionId the transaction id
+ */
+ public void setTransactionId(Long transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ /**
+ * Gets branch id.
+ *
+ * @return the branch id
+ */
+ public Long getBranchId() {
+ return branchId;
+ }
+
+ /**
+ * Sets branch id.
+ *
+ * @param branchId the branch id
+ */
+ public void setBranchId(Long branchId) {
+ this.branchId = branchId;
+ }
+
+ /**
+ * Gets resource id.
+ *
+ * @return the resource id
+ */
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * Sets resource id.
+ *
+ * @param resourceId the resource id
+ */
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ /**
+ * Gets table name.
+ *
+ * @return the table name
+ */
+ public String getTableName() {
+ return tableName;
+ }
+
+ /**
+ * Sets table name.
+ *
+ * @param tableName the table name
+ */
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ /**
+ * Gets pk.
+ *
+ * @return the pk
+ */
+ public String getPk() {
+ return pk;
+ }
+
+ /**
+ * Sets pk.
+ *
+ * @param pk the pk
+ */
+ public void setPk(String pk) {
+ this.pk = pk;
+ }
+
+ /**
+ * Gets row key.
+ *
+ * @return the row key
+ */
+ public String getRowKey() {
+ return rowKey;
+ }
+
+ /**
+ * Sets row key.
+ *
+ * @param rowKey the row key
+ */
+ public void setRowKey(String rowKey) {
+ this.rowKey = rowKey;
+ }
+
+ /**
+ * Gets feature.
+ *
+ * @return the feature
+ */
+ public String getFeature() {
+ return feature;
+ }
+
+ /**
+ * Sets feature.
+ *
+ * @param feature the feature
+ */
+ public void setFeature(String feature) {
+ this.feature = feature;
+ }
+
+ @Override
+ public String toString(){
+ return StringUtils.toString(this);
+ }
+}
+
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 e6f3dd07e09..60ec91b978d 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
@@ -18,6 +18,7 @@
import java.io.Serializable;
import java.nio.charset.Charset;
+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;
@@ -152,7 +153,7 @@ public abstract class AbstractMessage implements MessageCodec, Serializable {
/**
* The constant UTF8.
*/
- protected static final Charset UTF8 = Charset.forName("utf-8");
+ protected static final Charset UTF8 = Constants.DEFAULT_CHARSET;
/**
* The Ctx.
*/
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 3f5a40470e7..de8dcf726bd 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.5.2";
+ public static final String CURRENT = "0.6.0";
/**
* The constant VERSION_MAP.
diff --git a/core/src/main/java/io/seata/core/rpc/ChannelManager.java b/core/src/main/java/io/seata/core/rpc/ChannelManager.java
index d63086ea251..9de2904e93e 100644
--- a/core/src/main/java/io/seata/core/rpc/ChannelManager.java
+++ b/core/src/main/java/io/seata/core/rpc/ChannelManager.java
@@ -29,7 +29,6 @@
import io.seata.core.protocol.RegisterRMRequest;
import io.seata.core.protocol.RegisterTMRequest;
import io.seata.core.protocol.Version;
-import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import io.seata.core.rpc.netty.NettyPoolKey;
diff --git a/core/src/main/java/io/seata/core/rpc/RpcContext.java b/core/src/main/java/io/seata/core/rpc/RpcContext.java
index b605b72d067..6ba531eb16a 100644
--- a/core/src/main/java/io/seata/core/rpc/RpcContext.java
+++ b/core/src/main/java/io/seata/core/rpc/RpcContext.java
@@ -23,7 +23,6 @@
import java.util.concurrent.ConcurrentMap;
import io.seata.common.Constants;
-import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import io.seata.core.rpc.netty.NettyPoolKey;
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 44c33d31fdf..d5bf8625ca7 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
@@ -35,12 +35,7 @@
import io.seata.common.exception.FrameworkErrorCode;
import io.seata.common.exception.FrameworkException;
import io.seata.common.thread.NamedThreadFactory;
-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 io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelFuture;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java b/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
index 2ae97ced878..24c7a0f7c51 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
@@ -15,8 +15,6 @@
*/
package io.seata.core.rpc.netty;
-import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
-
import io.netty.channel.Channel;
/**
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 db29b780465..9d69006f9fb 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
@@ -21,7 +21,6 @@
import io.seata.common.util.NetUtil;
import io.seata.core.protocol.RegisterRMResponse;
import io.seata.core.protocol.RegisterTMResponse;
-import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import org.apache.commons.pool.KeyedPoolableObjectFactory;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java b/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
index d078a4df0da..ef0afc75f63 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
@@ -15,8 +15,6 @@
*/
package io.seata.core.rpc.netty;
-import io.seata.core.protocol.RegisterRMRequest;
-import io.seata.core.protocol.RegisterTMRequest;
import io.seata.core.protocol.RegisterRMRequest;
import io.seata.core.protocol.RegisterTMRequest;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java b/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
index 42a9eedbac5..98ba76fad03 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
@@ -15,8 +15,6 @@
*/
package io.seata.core.rpc.netty;
-import io.seata.core.protocol.AbstractMessage;
-
import io.netty.channel.Channel;
import io.seata.core.protocol.AbstractMessage;
diff --git a/core/src/main/java/io/seata/core/store/BranchTransactionDO.java b/core/src/main/java/io/seata/core/store/BranchTransactionDO.java
new file mode 100644
index 00000000000..63c784daf6c
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/BranchTransactionDO.java
@@ -0,0 +1,277 @@
+/*
+ * 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.store;
+
+
+import io.seata.common.util.StringUtils;
+import io.seata.core.model.BranchStatus;
+
+import java.util.Date;
+
+/**
+ * branch transaction data object
+ *
+ * @author zhangsen
+ * @data 2019 /3/26
+ */
+public class BranchTransactionDO {
+
+ private String xid;
+
+ private long transactionId;
+
+ private long branchId;
+
+ private String resourceGroupId;
+
+ private String resourceId;
+
+ private String lockKey;
+
+ private String branchType;
+
+ private int status = BranchStatus.Unknown.getCode();
+
+ private String clientId;
+
+ private String applicationData;
+
+ private Date gmtCreate;
+
+ private Date gmtModified;
+
+ /**
+ * Gets xid.
+ *
+ * @return the xid
+ */
+ public String getXid() {
+ return xid;
+ }
+
+ /**
+ * Sets xid.
+ *
+ * @param xid the xid
+ */
+ public void setXid(String xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * Gets transaction id.
+ *
+ * @return the transaction id
+ */
+ public long getTransactionId() {
+ return transactionId;
+ }
+
+ /**
+ * Sets transaction id.
+ *
+ * @param transactionId the transaction id
+ */
+ public void setTransactionId(long transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ /**
+ * Gets branch id.
+ *
+ * @return the branch id
+ */
+ public long getBranchId() {
+ return branchId;
+ }
+
+ /**
+ * Sets branch id.
+ *
+ * @param branchId the branch id
+ */
+ public void setBranchId(long branchId) {
+ this.branchId = branchId;
+ }
+
+ /**
+ * Gets resource group id.
+ *
+ * @return the resource group id
+ */
+ public String getResourceGroupId() {
+ return resourceGroupId;
+ }
+
+ /**
+ * Sets resource group id.
+ *
+ * @param resourceGroupId the resource group id
+ */
+ public void setResourceGroupId(String resourceGroupId) {
+ this.resourceGroupId = resourceGroupId;
+ }
+
+ /**
+ * Gets resource id.
+ *
+ * @return the resource id
+ */
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * Sets resource id.
+ *
+ * @param resourceId the resource id
+ */
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ /**
+ * Gets lock key.
+ *
+ * @return the lock key
+ */
+ public String getLockKey() {
+ return lockKey;
+ }
+
+ /**
+ * Sets lock key.
+ *
+ * @param lockKey the lock key
+ */
+ public void setLockKey(String lockKey) {
+ this.lockKey = lockKey;
+ }
+
+ /**
+ * Gets branch type.
+ *
+ * @return the branch type
+ */
+ public String getBranchType() {
+ return branchType;
+ }
+
+ /**
+ * Sets branch type.
+ *
+ * @param branchType the branch type
+ */
+ public void setBranchType(String branchType) {
+ this.branchType = branchType;
+ }
+
+ /**
+ * Gets status.
+ *
+ * @return the status
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets status.
+ *
+ * @param status the status
+ */
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ /**
+ * Gets client id.
+ *
+ * @return the client id
+ */
+ public String getClientId() {
+ return clientId;
+ }
+
+ /**
+ * Sets client id.
+ *
+ * @param clientId the client id
+ */
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ /**
+ * Gets application data.
+ *
+ * @return the application data
+ */
+ public String getApplicationData() {
+ return applicationData;
+ }
+
+ /**
+ * Sets application data.
+ *
+ * @param applicationData the application data
+ */
+ public void setApplicationData(String applicationData) {
+ this.applicationData = applicationData;
+ }
+
+ /**
+ * Gets gmt create.
+ *
+ * @return the gmt create
+ */
+ public Date getGmtCreate() {
+ return gmtCreate;
+ }
+
+ /**
+ * Sets gmt create.
+ *
+ * @param gmtCreate the gmt create
+ */
+ public void setGmtCreate(Date gmtCreate) {
+ this.gmtCreate = gmtCreate;
+ }
+
+ /**
+ * Gets gmt modified.
+ *
+ * @return the gmt modified
+ */
+ public Date getGmtModified() {
+ return gmtModified;
+ }
+
+ /**
+ * Sets gmt modified.
+ *
+ * @param gmtModified the gmt modified
+ */
+ public void setGmtModified(Date gmtModified) {
+ this.gmtModified = gmtModified;
+ }
+
+ @Override
+ public String toString(){
+ return StringUtils.toString(this);
+ }
+
+}
diff --git a/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java b/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java
new file mode 100644
index 00000000000..74c5e9ae13f
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java
@@ -0,0 +1,256 @@
+/*
+ * 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.store;
+
+
+import io.seata.common.util.StringUtils;
+
+import java.util.Date;
+
+/**
+ * Global Transaction data object
+ *
+ * @author zhangsen
+ * @data 2019 /3/26
+ */
+public class GlobalTransactionDO {
+
+ private String xid;
+
+ private long transactionId;
+
+ private int status;
+
+ private String applicationId;
+
+ private String transactionServiceGroup;
+
+ private String transactionName;
+
+ private int timeout;
+
+ private long beginTime;
+
+ private String applicationData;
+
+ private Date gmtCreate;
+
+ private Date gmtModified;
+
+ /**
+ * Gets xid.
+ *
+ * @return the xid
+ */
+ public String getXid() {
+ return xid;
+ }
+
+ /**
+ * Sets xid.
+ *
+ * @param xid the xid
+ */
+ public void setXid(String xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * Gets status.
+ *
+ * @return the status
+ */
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets status.
+ *
+ * @param status the status
+ */
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ /**
+ * Gets application id.
+ *
+ * @return the application id
+ */
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ /**
+ * Sets application id.
+ *
+ * @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.
+ *
+ * @param transactionServiceGroup the transaction service group
+ */
+ public void setTransactionServiceGroup(String transactionServiceGroup) {
+ this.transactionServiceGroup = transactionServiceGroup;
+ }
+
+ /**
+ * Gets transaction name.
+ *
+ * @return the transaction name
+ */
+ public String getTransactionName() {
+ return transactionName;
+ }
+
+ /**
+ * Sets transaction name.
+ *
+ * @param transactionName the transaction name
+ */
+ public void setTransactionName(String transactionName) {
+ this.transactionName = transactionName;
+ }
+
+ /**
+ * Gets timeout.
+ *
+ * @return the timeout
+ */
+ public int getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * Sets timeout.
+ *
+ * @param timeout the timeout
+ */
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Gets begin time.
+ *
+ * @return the begin time
+ */
+ public long getBeginTime() {
+ return beginTime;
+ }
+
+ /**
+ * Sets begin time.
+ *
+ * @param beginTime the begin time
+ */
+ public void setBeginTime(long beginTime) {
+ this.beginTime = beginTime;
+ }
+
+ /**
+ * Gets transaction id.
+ *
+ * @return the transaction id
+ */
+ public long getTransactionId() {
+ return transactionId;
+ }
+
+ /**
+ * Sets transaction id.
+ *
+ * @param transactionId the transaction id
+ */
+ public void setTransactionId(long transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ /**
+ * Gets application data.
+ *
+ * @return the application data
+ */
+ public String getApplicationData() {
+ return applicationData;
+ }
+
+ /**
+ * Sets application data.
+ *
+ * @param applicationData the application data
+ */
+ public void setApplicationData(String applicationData) {
+ this.applicationData = applicationData;
+ }
+
+ /**
+ * Gets gmt create.
+ *
+ * @return the gmt create
+ */
+ public Date getGmtCreate() {
+ return gmtCreate;
+ }
+
+ /**
+ * Sets gmt create.
+ *
+ * @param gmtCreate the gmt create
+ */
+ public void setGmtCreate(Date gmtCreate) {
+ this.gmtCreate = gmtCreate;
+ }
+
+ /**
+ * Gets gmt modified.
+ *
+ * @return the gmt modified
+ */
+ public Date getGmtModified() {
+ return gmtModified;
+ }
+
+ /**
+ * Sets gmt modified.
+ *
+ * @param gmtModified the gmt modified
+ */
+ public void setGmtModified(Date gmtModified) {
+ this.gmtModified = gmtModified;
+ }
+
+ @Override
+ public String toString(){
+ return StringUtils.toString(this);
+ }
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/LockDO.java b/core/src/main/java/io/seata/core/store/LockDO.java
new file mode 100644
index 00000000000..51b242de627
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/LockDO.java
@@ -0,0 +1,178 @@
+/*
+ * 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.store;
+
+import io.seata.common.util.StringUtils;
+
+/**
+ * The type Lock do.
+ *
+ * @author zhangsen
+ * @data 2019 /4/25
+ */
+public class LockDO {
+
+ private String xid;
+
+ private Long transactionId;
+
+ private Long branchId;
+
+ private String resourceId;
+
+ private String tableName;
+
+ private String pk;
+
+ private String rowKey;
+
+ /**
+ * Instantiates a new Lock do.
+ */
+ public LockDO() {
+ }
+
+ /**
+ * Gets xid.
+ *
+ * @return the xid
+ */
+ public String getXid() {
+ return xid;
+ }
+
+ /**
+ * Sets xid.
+ *
+ * @param xid the xid
+ */
+ public void setXid(String xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * Gets transaction id.
+ *
+ * @return the transaction id
+ */
+ public Long getTransactionId() {
+ return transactionId;
+ }
+
+ /**
+ * Sets transaction id.
+ *
+ * @param transactionId the transaction id
+ */
+ public void setTransactionId(Long transactionId) {
+ this.transactionId = transactionId;
+ }
+
+ /**
+ * Gets resource id.
+ *
+ * @return the resource id
+ */
+ public String getResourceId() {
+ return resourceId;
+ }
+
+ /**
+ * Sets resource id.
+ *
+ * @param resourceId the resource id
+ */
+ public void setResourceId(String resourceId) {
+ this.resourceId = resourceId;
+ }
+
+ /**
+ * Gets row key.
+ *
+ * @return the row key
+ */
+ public String getRowKey() {
+ return rowKey;
+ }
+
+ /**
+ * Sets row key.
+ *
+ * @param rowKey the row key
+ */
+ public void setRowKey(String rowKey) {
+ this.rowKey = rowKey;
+ }
+
+ /**
+ * Gets table name.
+ *
+ * @return the table name
+ */
+ public String getTableName() {
+ return tableName;
+ }
+
+ /**
+ * Sets table name.
+ *
+ * @param tableName the table name
+ */
+ public void setTableName(String tableName) {
+ this.tableName = tableName;
+ }
+
+ /**
+ * Gets pk.
+ *
+ * @return the pk
+ */
+ public String getPk() {
+ return pk;
+ }
+
+ /**
+ * Sets pk.
+ *
+ * @param pk the pk
+ */
+ public void setPk(String pk) {
+ this.pk = pk;
+ }
+
+ /**
+ * Gets branch id.
+ *
+ * @return the branch id
+ */
+ public Long getBranchId() {
+ return branchId;
+ }
+
+ /**
+ * Sets branch id.
+ *
+ * @param branchId the branch id
+ */
+ public void setBranchId(Long branchId) {
+ this.branchId = branchId;
+ }
+
+ @Override
+ public String toString() {
+ return StringUtils.toString(this);
+ }
+}
diff --git a/core/src/main/java/io/seata/core/store/LockStore.java b/core/src/main/java/io/seata/core/store/LockStore.java
new file mode 100644
index 00000000000..49e92e6ab10
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/LockStore.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.store;
+
+import java.util.List;
+
+/**
+ * The interface Lock store.
+ *
+ * @author zhangsen
+ * @data 2019 /4/25
+ */
+public interface LockStore {
+
+ /**
+ * Acquire lock boolean.
+ *
+ * @param lockDO the lock do
+ * @return the boolean
+ */
+ boolean acquireLock(LockDO lockDO);
+
+
+ /**
+ * Acquire lock boolean.
+ *
+ * @param lockDOs the lock d os
+ * @return the boolean
+ */
+ boolean acquireLock(List lockDOs);
+
+ /**
+ * Un lock boolean.
+ *
+ * @param lockDO the lock do
+ * @return the boolean
+ */
+ boolean unLock(LockDO lockDO);
+
+ /**
+ * Un lock boolean.
+ *
+ * @param lockDOs the lock d os
+ * @return the boolean
+ */
+ boolean unLock(List lockDOs);
+
+ /**
+ * Is lockable boolean.
+ *
+ * @param lockDOs the lock do
+ * @return the boolean
+ */
+ boolean isLockable(List lockDOs);
+}
diff --git a/core/src/main/java/io/seata/core/store/LogStore.java b/core/src/main/java/io/seata/core/store/LogStore.java
new file mode 100644
index 00000000000..f02b0ddc6d2
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/LogStore.java
@@ -0,0 +1,110 @@
+/*
+ * 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.store;
+
+
+import java.util.List;
+
+/**
+ * the transaction log store
+ *
+ * @author zhangsen
+ * @data 2019 /3/26
+ */
+public interface LogStore {
+
+ /**
+ * Query global transaction do global transaction do.
+ *
+ * @param xid the xid
+ * @return the global transaction do
+ */
+ GlobalTransactionDO queryGlobalTransactionDO(String xid);
+
+ /**
+ * Query global transaction do global transaction do.
+ *
+ * @param transactionId the transaction id
+ * @return the global transaction do
+ */
+ GlobalTransactionDO queryGlobalTransactionDO(long transactionId);
+
+ /**
+ * Query global transaction do list.
+ *
+ * @param status the status
+ * @param limit the limit
+ * @return the list
+ */
+ List queryGlobalTransactionDO(int[] status, int limit);
+
+ /**
+ * Insert global transaction do boolean.
+ *
+ * @param globalTransactionDO the global transaction do
+ * @return the boolean
+ */
+ boolean insertGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
+
+ /**
+ * Update global transaction do boolean.
+ *
+ * @param globalTransactionDO the global transaction do
+ * @return the boolean
+ */
+ boolean updateGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
+
+ /**
+ * Delete global transaction do boolean.
+ *
+ * @param globalTransactionDO the global transaction do
+ * @return the boolean
+ */
+ boolean deleteGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
+
+ /**
+ * Query branch transaction do boolean.
+ *
+ * @param xid the xid
+ * @return the boolean
+ */
+ List queryBranchTransactionDO(String xid);
+
+ /**
+ * Insert branch transaction do boolean.
+ *
+ * @param branchTransactionDO the branch transaction do
+ * @return the boolean
+ */
+ boolean insertBranchTransactionDO(BranchTransactionDO branchTransactionDO);
+
+ /**
+ * Update branch transaction do boolean.
+ *
+ * @param branchTransactionDO the branch transaction do
+ * @return the boolean
+ */
+ boolean updateBranchTransactionDO(BranchTransactionDO branchTransactionDO);
+
+ /**
+ * Delete branch transaction do boolean.
+ *
+ * @param branchTransactionDO the branch transaction do
+ * @return the boolean
+ */
+ boolean deleteBranchTransactionDO(BranchTransactionDO branchTransactionDO);
+
+}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java b/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java
new file mode 100644
index 00000000000..2cdbcb00ce6
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java
@@ -0,0 +1,148 @@
+/*
+ * 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.store.db;
+
+import io.seata.common.exception.StoreException;
+import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+import io.seata.core.constants.DBType;
+
+/**
+ * The type Abstract data source generator.
+ *
+ * @author zhangsen
+ * @data 2019 /4/24
+ */
+public abstract class AbstractDataSourceGenerator implements DataSourceGenerator {
+
+ /**
+ * The constant CONFIG.
+ */
+ protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
+
+ /**
+ * Get db type db type.
+ *
+ * @return the db type
+ */
+ protected DBType getDBType(){
+ return DBType.valueof(CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE));
+ }
+
+ /**
+ * Get url string.
+ *
+ * @return the string
+ */
+ protected String getUrl(){
+ String url = CONFIG.getConfig(ConfigurationKeys.STORE_DB_URL);
+ if(StringUtils.isBlank(url)){
+ throw new StoreException("the {store.db.url} can't empty.");
+ }
+ return url;
+ }
+
+ /**
+ * Get user string.
+ *
+ * @return the string
+ */
+ protected String getUser(){
+ String user = CONFIG.getConfig(ConfigurationKeys.STORE_DB_USER);
+ if(StringUtils.isBlank(user)){
+ throw new StoreException("the {store.db.user} can't empty.");
+ }
+ return user;
+ }
+
+ /**
+ * Get password string.
+ *
+ * @return the string
+ */
+ protected String getPassword(){
+ String password = CONFIG.getConfig(ConfigurationKeys.STORE_DB_PASSWORD);
+ return password;
+ }
+
+ /**
+ * Get min conn int.
+ *
+ * @return the int
+ */
+ protected int getMinConn(){
+ int minConn = CONFIG.getInt(ConfigurationKeys.STORE_DB_MIN_CONN);
+ return minConn<0?0:minConn;
+ }
+
+ /**
+ * Get max conn int.
+ *
+ * @return the int
+ */
+ protected int getMaxConn(){
+ int maxConn = CONFIG.getInt(ConfigurationKeys.STORE_DB_MAX_CONN);
+ return maxConn<0?1:maxConn;
+ }
+
+
+ /**
+ * Get driver name string.
+ *
+ * @param dbType the db type
+ * @return the string
+ */
+ protected static String getDriverName(DBType dbType){
+ if(DBType.H2.equals(dbType)){
+ return "org.h2.Driver";
+ }else if(DBType.MYSQL.equals(dbType)){
+ return "com.mysql.jdbc.Driver";
+ }else if(DBType.ORACLE.equals(dbType)){
+ return "oracle.jdbc.OracleDriver";
+ }else if(DBType.SYBAEE.equals(dbType)){
+ return "com.sybase.jdbc2.jdbc.SybDriver";
+ }else if(DBType.SQLSERVER.equals(dbType)){
+ return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
+ }else if(DBType.SQLITE.equals(dbType)){
+ return "org.sqlite.JDBC";
+ }else if(DBType.POSTGRESQL.equals(dbType)){
+ return "org.postgresql.Driver";
+ }else if(DBType.ACCESS.equals(dbType)){
+ return "com.hxtt.sql.access.AccessDriver";
+ }else if(DBType.DB2.equals(dbType)){
+ return "com.ibm.db2.jcc.DB2Driver";
+ }else {
+ throw new StoreException("Unsupported database type, dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get validation query string.
+ *
+ * @param dbType the db type
+ * @return the string
+ */
+ protected String getValidationQuery(DBType dbType){
+ if(DBType.ORACLE.equals(dbType)){
+ return "select sysdate from dual";
+ }else {
+ return "select 1";
+ }
+ }
+
+}
diff --git a/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java b/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java
new file mode 100644
index 00000000000..5687513969b
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.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.core.store.db;
+
+import javax.sql.DataSource;
+
+/**
+ * The interface Data source generator.
+ *
+ * @author zhangsen
+ * @data 2019 /4/24
+ */
+public interface DataSourceGenerator {
+
+ /**
+ * create DataSource from config
+ *
+ * @return data source
+ */
+ DataSource generateDataSource();
+
+}
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
new file mode 100644
index 00000000000..b1aac288814
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
@@ -0,0 +1,356 @@
+/*
+ * 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.store.db;
+
+import io.seata.common.exception.StoreException;
+import io.seata.common.executor.Initialize;
+import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+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.ArrayList;
+import java.util.List;
+
+/**
+ * The type Data base lock store.
+ *
+ * @author zhangsen
+ * @data 2019 /4/25
+ */
+@LoadLevel(name = "db")
+public class LockStoreDataBaseDAO implements LockStore, Initialize {
+
+ /**
+ * The constant CONFIG.
+ */
+ protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
+
+ /**
+ * The Log store data source.
+ */
+ protected DataSource logStoreDataSource = null;
+
+ /**
+ * The Lock table.
+ */
+ protected String lockTable;
+
+ /**
+ * The Db type.
+ */
+ protected String dbType;
+
+ /**
+ * Instantiates a new Data base lock store dao.
+ *
+ * @param logStoreDataSource the log store data source
+ */
+ public LockStoreDataBaseDAO(DataSource logStoreDataSource) {
+ this.logStoreDataSource = logStoreDataSource;
+ }
+
+ @Override
+ public void init() {
+ lockTable = CONFIG.getConfig(ConfigurationKeys.LOCK_DB_TABLE, ConfigurationKeys.LOCK_DB_DEFAULT_TABLE);
+ dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
+ if (StringUtils.isBlank(dbType)) {
+ throw new StoreException("there must be db type.");
+ }
+ if (logStoreDataSource == null) {
+ throw new StoreException("there must be logStoreDataSource.");
+ }
+ }
+
+ @Override
+ public boolean acquireLock(LockDO lockDO) {
+ List locks = new ArrayList<>();
+ locks.add(lockDO);
+ return acquireLock(locks);
+ }
+
+ @Override
+ public boolean acquireLock(List lockDOs) {
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(false);
+
+ //check lock
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < lockDOs.size(); i++){
+ sb.append("?");
+ if( i != (lockDOs.size() - 1)){
+ sb.append(", ");
+ }
+ }
+ boolean canLock = true, isReLock = false;
+ //query
+ String checkLockSQL = LockStoreSqls.getCheckLockableSql(lockTable, sb.toString(), dbType);
+ ps = conn.prepareStatement(checkLockSQL);
+ for (int i = 0; i < lockDOs.size(); i++){
+ ps.setString(i+1, lockDOs.get(i).getRowKey());
+ }
+ rs = ps.executeQuery();
+ while (rs.next()) {
+ if(StringUtils.equals(rs.getString("xid"), lockDOs.get(0).getXid())){
+ isReLock = true;
+ }else {
+ canLock &= false;
+ }
+ }
+
+ if(!canLock){
+ conn.rollback();
+ return false;
+ }
+
+ if(isReLock){
+ conn.rollback();
+ return true;
+ }
+
+ //lock
+ for(LockDO lockDO : lockDOs){
+ if(!doAcquireLock(conn, lockDO)) {
+ conn.rollback();
+ return false;
+ }
+ }
+ conn.commit();
+ return true;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean unLock(LockDO lockDO) {
+ List locks = new ArrayList<>();
+ locks.add(lockDO);
+ return unLock(locks);
+ }
+
+ @Override
+ public boolean unLock(List lockDOs) {
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i< lockDOs.size(); i++){
+ sb.append("?");
+ if(i != (lockDOs.size() - 1)){
+ sb.append(", ");
+ }
+ }
+ //batch release lock
+ String batchDeleteSQL = LockStoreSqls.getBatchDeleteLockSql(lockTable, sb.toString(), dbType);
+ ps = conn.prepareStatement(batchDeleteSQL);
+ ps.setString(1, lockDOs.get(0).getXid());
+ for(int i = 0; i< lockDOs.size(); i++){
+ ps.setString(i+2, lockDOs.get(i).getRowKey());
+ }
+ return ps.executeUpdate() > 0;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean isLockable(List lockDOs) {
+ Connection conn = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ if(!checkLockable(conn, lockDOs)){
+ return false;
+ }
+ return true;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Do acquire lock boolean.
+ *
+ * @param conn the conn
+ * @param lockDO the lock do
+ * @return the boolean
+ */
+ protected boolean doAcquireLock(Connection conn, LockDO lockDO) {
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ //insert
+ String insertLockSQL = LockStoreSqls.getInsertLockSQL(lockTable, dbType);
+ ps = conn.prepareStatement(insertLockSQL);
+ ps.setString(1, lockDO.getXid());
+ ps.setLong(2, lockDO.getTransactionId());
+ ps.setLong(3, lockDO.getBranchId());
+ ps.setString(4, lockDO.getResourceId());
+ ps.setString(5, lockDO.getTableName());
+ ps.setString(6, lockDO.getPk());
+ ps.setString(7, lockDO.getRowKey());
+ return ps.executeUpdate() > 0;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Check lock boolean.
+ *
+ * @param conn the conn
+ * @param lockDOs the lock do
+ * @return the boolean
+ */
+ protected boolean checkLockable(Connection conn, List lockDOs){
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < lockDOs.size(); i++){
+ sb.append("?");
+ if( i != (lockDOs.size() - 1)){
+ sb.append(", ");
+ }
+ }
+
+ //query
+ String checkLockSQL = LockStoreSqls.getCheckLockableSql(lockTable, sb.toString(), dbType);
+ ps = conn.prepareStatement(checkLockSQL);
+ for (int i = 0; i < lockDOs.size(); i++){
+ ps.setString(i+1, lockDOs.get(i).getRowKey());
+ }
+ rs = ps.executeQuery();
+ while (rs.next()) {
+ String xid = rs.getString("xid");
+ if(!StringUtils.equals(xid, lockDOs.get(0).getXid())){
+ return false;
+ }
+ }
+ return true;
+ }catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (rs != null) {
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets lock table.
+ *
+ * @param lockTable the lock table
+ */
+ public void setLockTable(String lockTable) {
+ this.lockTable = lockTable;
+ }
+
+ /**
+ * Sets db type.
+ *
+ * @param dbType the db type
+ */
+ public void setDbType(String dbType) {
+ this.dbType = dbType;
+ }
+
+ /**
+ * Sets log store data source.
+ *
+ * @param logStoreDataSource the log store data source
+ */
+ public void setLogStoreDataSource(DataSource logStoreDataSource) {
+ this.logStoreDataSource = logStoreDataSource;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/LockStoreSqls.java b/core/src/main/java/io/seata/core/store/db/LockStoreSqls.java
new file mode 100644
index 00000000000..7c95473e269
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/LockStoreSqls.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.core.store.db;
+
+import io.seata.common.exception.NotSupportYetException;
+import io.seata.core.constants.DBType;
+
+/**
+ * The type Lock store sqls.
+ *
+ * @author zhangsen
+ * @data 2019 /4/26
+ */
+public class LockStoreSqls {
+
+ /**
+ * The constant LOCK_TABLE_PLACEHOLD.
+ */
+ public static final String LOCK_TABLE_PLACEHOLD = " #lock_table# ";
+
+ /**
+ * The constant IN_PARAMS_PLACEHOLD.
+ */
+ public static final String IN_PARAMS_PLACEHOLD = " #in_params# ";
+
+ /**
+ * The constant ALL_COLUMNS.
+ */
+ public static final String ALL_COLUMNS = "xid, transaction_id, branch_id, resource_id, table_name, pk, row_key, gmt_create, gmt_modified";
+
+ /**
+ * The constant INSERT_LOCK_SQL_MYSQL.
+ */
+ public static final String INSERT_LOCK_SQL_MYSQL = "insert into " + LOCK_TABLE_PLACEHOLD + "("+ ALL_COLUMNS +")" +
+ "values (?, ?, ?, ?, ?, ?, ?, now(), now())";
+
+ /**
+ * The constant INSERT_LOCK_SQL_ORACLE.
+ */
+ public static final String INSERT_LOCK_SQL_ORACLE = "insert into " + LOCK_TABLE_PLACEHOLD + "("+ ALL_COLUMNS +")" +
+ "values (?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)";
+
+ /**
+ * The constant DELETE_LOCK_SQL.
+ */
+ public static final String DELETE_LOCK_SQL = "delete from " + LOCK_TABLE_PLACEHOLD + " where row_key = ? and xid = ?";
+
+ /**
+ * The constant BATCH_DELETE_LOCK_SQL.
+ */
+ public static final String BATCH_DELETE_LOCK_SQL = "delete from " + LOCK_TABLE_PLACEHOLD + " where xid = ? and row_key in ("+ IN_PARAMS_PLACEHOLD +") ";
+
+ /**
+ * The constant QUERY_LOCK_SQL.
+ */
+ public static final String QUERY_LOCK_SQL = "select " + ALL_COLUMNS + " from " + LOCK_TABLE_PLACEHOLD
+ + " where row_key = ? ";
+
+ /**
+ * The constant CHECK_LOCK_SQL.
+ */
+ public static final String CHECK_LOCK_SQL = "select " + ALL_COLUMNS + " from " + LOCK_TABLE_PLACEHOLD
+ + " where row_key in ("+ IN_PARAMS_PLACEHOLD +")" ;
+
+ /**
+ * Get insert lock sql string.
+ *
+ * @param lockTable the lock table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getInsertLockSQL(String lockTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return INSERT_LOCK_SQL_MYSQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return INSERT_LOCK_SQL_ORACLE.replace(LOCK_TABLE_PLACEHOLD, lockTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get delete lock sql string.
+ *
+ * @param lockTable the lock table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getDeleteLockSql(String lockTable, String dbType){
+ return DELETE_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
+ }
+
+ /**
+ * Get batch delete lock sql string.
+ *
+ * @param lockTable the lock table
+ * @param paramPlaceHold the param place hold
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getBatchDeleteLockSql(String lockTable, String paramPlaceHold, String dbType){
+ return BATCH_DELETE_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable).replace(IN_PARAMS_PLACEHOLD, paramPlaceHold);
+ }
+
+ /**
+ * Get query lock sql string.
+ *
+ * @param lockTable the lock table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getQueryLockSql(String lockTable, String dbType){
+ return QUERY_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
+ }
+
+ /**
+ * Get check lock sql string.
+ *
+ * @param lockTable the lock table
+ * @param paramPlaceHold the param place hold
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getCheckLockableSql(String lockTable, String paramPlaceHold, String dbType){
+ return CHECK_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable).replace(IN_PARAMS_PLACEHOLD, paramPlaceHold);
+ }
+
+}
diff --git a/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java b/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java
new file mode 100644
index 00000000000..4248ce45929
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java
@@ -0,0 +1,533 @@
+/*
+ * 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.store.db;
+
+import io.seata.common.exception.StoreException;
+import io.seata.common.executor.Initialize;
+import io.seata.common.loader.LoadLevel;
+import io.seata.common.util.StringUtils;
+import io.seata.config.Configuration;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
+import io.seata.core.store.BranchTransactionDO;
+import io.seata.core.store.GlobalTransactionDO;
+import io.seata.core.store.LogStore;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The type Log store data base dao.
+ *
+ * @author zhangsen
+ * @data 2019 /4/2
+ */
+@LoadLevel(name = "db")
+public class LogStoreDataBaseDAO implements LogStore, Initialize {
+
+ /**
+ * The constant CONFIG.
+ */
+ protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
+
+ /**
+ * The Log store data source.
+ */
+ protected DataSource logStoreDataSource = null;
+
+ /**
+ * The Global table.
+ */
+ protected String globalTable;
+
+ /**
+ * The Brach table.
+ */
+ protected String brachTable;
+
+ private String dbType;
+
+ /**
+ * Instantiates a new Log store data base dao.
+ */
+ public LogStoreDataBaseDAO(){
+ }
+
+ /**
+ * Instantiates a new Log store data base dao.
+ *
+ * @param logStoreDataSource the log store data source
+ */
+ public LogStoreDataBaseDAO(DataSource logStoreDataSource) {
+ this.logStoreDataSource = logStoreDataSource;
+ }
+
+ @Override
+ public void init() {
+ globalTable = CONFIG.getConfig(ConfigurationKeys.STORE_DB_GLOBAL_TABLE, ConfigurationKeys.STORE_DB_GLOBAL_DEFAULT_TABLE);
+ brachTable = CONFIG.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, ConfigurationKeys.STORE_DB_BRANCH_DEFAULT_TABLE);
+ dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
+ if(StringUtils.isBlank(dbType)){
+ throw new StoreException("there must be db type.");
+ }
+ if(logStoreDataSource == null){
+ throw new StoreException("there must be logStoreDataSource.");
+ }
+ }
+
+ @Override
+ public GlobalTransactionDO queryGlobalTransactionDO(String xid) {
+ String sql = LogStoreSqls.getQueryGlobalTransactionSQL(globalTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, xid);
+ rs = ps.executeQuery();
+ if(rs.next()){
+ return convertGlobalTransactionDO(rs);
+ }else {
+ return null;
+ }
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(rs != null){
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public GlobalTransactionDO queryGlobalTransactionDO(long transactionId){
+ String sql = LogStoreSqls.getQueryGlobalTransactionSQLByTransactionId(globalTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setLong(1, transactionId);
+ rs = ps.executeQuery();
+ if(rs.next()){
+ return convertGlobalTransactionDO(rs);
+ }else {
+ return null;
+ }
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(rs != null){
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public List queryGlobalTransactionDO(int[] statuses, int limit) {
+ List ret = new ArrayList();
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < statuses.length; i ++){
+ sb.append("?");
+ if(i != (statuses.length -1)){
+ sb.append(", ");
+ }
+ }
+
+ String sql = LogStoreSqls.getQueryGlobalTransactionSQLByStatus(globalTable, dbType, sb.toString());
+ ps = conn.prepareStatement(sql);
+ for(int i = 0; i < statuses.length; i ++){
+ int status = statuses[i];
+ ps.setInt(i+1, status);
+ }
+ ps.setInt(statuses.length +1, limit);
+ rs = ps.executeQuery();
+ while(rs.next()){
+ ret.add(convertGlobalTransactionDO(rs));
+ }
+ return ret;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(rs != null){
+ try {
+ rs.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean insertGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
+ String sql = LogStoreSqls.getInsertGlobalTransactionSQL(globalTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try{
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, globalTransactionDO.getXid());
+ ps.setLong(2, globalTransactionDO.getTransactionId());
+ ps.setInt(3, globalTransactionDO.getStatus());
+ ps.setString(4, globalTransactionDO.getApplicationId());
+ ps.setString(5, globalTransactionDO.getTransactionServiceGroup());
+ ps.setString(6, globalTransactionDO.getTransactionName());
+ ps.setInt(7, globalTransactionDO.getTimeout());
+ ps.setLong(8, globalTransactionDO.getBeginTime());
+ ps.setString(9, globalTransactionDO.getApplicationData());
+ return ps.executeUpdate() > 0;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean updateGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
+ String sql = LogStoreSqls.getUpdateGlobalTransactionStatusSQL(globalTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try{
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setInt(1, globalTransactionDO.getStatus());
+ ps.setString(2, globalTransactionDO.getXid());
+ return ps.executeUpdate() > 0;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean deleteGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
+ String sql = LogStoreSqls.getDeleteGlobalTransactionSQL(globalTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try{
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, globalTransactionDO.getXid());
+ return ps.executeUpdate() > 0;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public List queryBranchTransactionDO(String xid) {
+ List rets = new ArrayList<>();
+ String sql = LogStoreSqls.getQureyBranchTransaction(brachTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, xid);
+
+ ResultSet rs = ps.executeQuery();
+ while(rs.next()){
+ rets.add(convertBranchTransactionDO(rs));
+ }
+ return rets;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean insertBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
+ String sql = LogStoreSqls.getInsertBranchTransactionSQL(brachTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try {
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, branchTransactionDO.getXid());
+ ps.setLong(2, branchTransactionDO.getTransactionId());
+ ps.setLong(3, branchTransactionDO.getBranchId());
+ ps.setString(4, branchTransactionDO.getResourceGroupId());
+ ps.setString(5, branchTransactionDO.getResourceId());
+ ps.setString(6, branchTransactionDO.getLockKey());
+ ps.setString(7, branchTransactionDO.getBranchType());
+ ps.setInt(8, branchTransactionDO.getStatus());
+ ps.setString(9, branchTransactionDO.getClientId());
+ ps.setString(10, branchTransactionDO.getApplicationData());
+ return ps.executeUpdate() > 0;
+ } catch (SQLException e) {
+ throw new StoreException(e);
+ } finally {
+ if (ps != null) {
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean updateBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
+ String sql = LogStoreSqls.getUpdateBranchTransactionStatusSQL(brachTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try{
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setInt(1, branchTransactionDO.getStatus());
+ ps.setString(2, branchTransactionDO.getXid());
+ ps.setLong(3, branchTransactionDO.getBranchId());
+ return ps.executeUpdate() > 0;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean deleteBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
+ String sql = LogStoreSqls.getDeleteBranchTransactionByBranchIdSQL(brachTable, dbType);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try{
+ conn = logStoreDataSource.getConnection();
+ conn.setAutoCommit(true);
+ ps = conn.prepareStatement(sql);
+ ps.setString(1, branchTransactionDO.getXid());
+ ps.setLong(2, branchTransactionDO.getBranchId());
+ return ps.executeUpdate() > 0;
+ }catch (SQLException e){
+ throw new StoreException(e);
+ }finally {
+ if(ps != null){
+ try {
+ ps.close();
+ } catch (SQLException e) {
+ }
+ }
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+
+ private GlobalTransactionDO convertGlobalTransactionDO(ResultSet rs) throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid(rs.getString("xid"));
+ globalTransactionDO.setStatus(rs.getInt("status"));
+ globalTransactionDO.setApplicationId(rs.getString("application_id"));
+ globalTransactionDO.setBeginTime(rs.getLong("begin_time"));
+ globalTransactionDO.setTimeout(rs.getInt("timeout"));
+ globalTransactionDO.setTransactionId(rs.getLong("transaction_id"));
+ globalTransactionDO.setTransactionName(rs.getString("transaction_name"));
+ globalTransactionDO.setTransactionServiceGroup(rs.getString("transaction_service_group"));
+ globalTransactionDO.setApplicationData(rs.getString("application_data"));
+ globalTransactionDO.setGmtCreate(rs.getTimestamp("gmt_create"));
+ globalTransactionDO.setGmtModified(rs.getTimestamp("gmt_modified"));
+ return globalTransactionDO;
+ }
+
+ private BranchTransactionDO convertBranchTransactionDO(ResultSet rs) throws SQLException {
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceGroupId(rs.getString("resource_group_id"));
+ branchTransactionDO.setStatus(rs.getInt("status"));
+ branchTransactionDO.setApplicationData(rs.getString("application_data"));
+ branchTransactionDO.setClientId(rs.getString("client_id"));
+ branchTransactionDO.setLockKey(rs.getString("lock_key"));
+ branchTransactionDO.setXid(rs.getString("xid"));
+ branchTransactionDO.setResourceId(rs.getString("resource_id"));
+ branchTransactionDO.setBranchId(rs.getLong("branch_id"));
+ branchTransactionDO.setBranchType(rs.getString("branch_type"));
+ branchTransactionDO.setTransactionId(rs.getLong("transaction_id"));
+ branchTransactionDO.setGmtCreate(rs.getTimestamp("gmt_create"));
+ branchTransactionDO.setGmtModified(rs.getTimestamp("gmt_modified"));
+ return branchTransactionDO;
+ }
+
+ /**
+ * Sets log store data source.
+ *
+ * @param logStoreDataSource the log store data source
+ */
+ public void setLogStoreDataSource(DataSource logStoreDataSource) {
+ this.logStoreDataSource = logStoreDataSource;
+ }
+
+ /**
+ * Sets global table.
+ *
+ * @param globalTable the global table
+ */
+ public void setGlobalTable(String globalTable) {
+ this.globalTable = globalTable;
+ }
+
+ /**
+ * Sets brach table.
+ *
+ * @param brachTable the brach table
+ */
+ public void setBrachTable(String brachTable) {
+ this.brachTable = brachTable;
+ }
+
+ /**
+ * Sets db type.
+ *
+ * @param dbType the db type
+ */
+ public void setDbType(String dbType) {
+ this.dbType = dbType;
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java b/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java
new file mode 100644
index 00000000000..69308324d63
--- /dev/null
+++ b/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java
@@ -0,0 +1,323 @@
+/*
+ * 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.store.db;
+
+
+import io.seata.common.exception.NotSupportYetException;
+import io.seata.core.constants.DBType;
+
+/**
+ * database log store SQLs
+ *
+ * @author zhangsen
+ * @data 2019 /4/2
+ */
+public class LogStoreSqls {
+
+ /**
+ * The constant GLOBAL_TABLE_PLACEHOLD.
+ */
+ public static final String GLOBAL_TABLE_PLACEHOLD = " #global_table# ";
+
+ /**
+ * The constant BRANCH_TABLE_PLACEHOLD.
+ */
+ public static final String BRANCH_TABLE_PLACEHOLD = " #branch_table# ";
+
+
+ /**
+ * The constant PRAMETER_PLACEHOLD.
+ */
+ public static final String PRAMETER_PLACEHOLD = " #PRAMETER_PLACEHOLD# ";
+
+ /**
+ * The constant ALL_GLOBAL_COLUMNS.
+ */
+ public static final String ALL_GLOBAL_COLUMNS = "xid, transaction_id, status, application_id, transaction_service_group, transaction_name, timeout, begin_time, application_data, gmt_create, gmt_modified ";
+
+ /**
+ * The constant ALL_BRANCH_COLUMNS.
+ */
+ protected static final String ALL_BRANCH_COLUMNS = "xid, transaction_id, branch_id, resource_group_id, resource_id, lock_key, branch_type, status, client_id, application_data, gmt_create, gmt_modified ";
+
+ /**
+ * The constant INSERT_GLOBAL_TRANSACTION_MYSQL.
+ */
+ public static final String INSERT_GLOBAL_TRANSACTION_MYSQL = "insert into " + GLOBAL_TABLE_PLACEHOLD + "("+ ALL_GLOBAL_COLUMNS +")" +
+ "values(?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now()) ";
+
+ /**
+ * The constant INSERT_GLOBAL_TRANSACTION_ORACLE.
+ */
+ public static final String INSERT_GLOBAL_TRANSACTION_ORACLE = "insert into " + GLOBAL_TABLE_PLACEHOLD + "("+ ALL_GLOBAL_COLUMNS +")" +
+ "values(?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate) ";
+
+ /**
+ * The constant UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL.
+ */
+ public static final String UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL = "update "+ GLOBAL_TABLE_PLACEHOLD + " set status = ?, gmt_modified = now() where xid = ?";
+
+ /**
+ * The constant UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE.
+ */
+ public static final String UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE = "update "+ GLOBAL_TABLE_PLACEHOLD + " set status = ?, gmt_modified = sysdate where xid = ?";
+
+ /**
+ * The constant DELETE_GLOBAL_TRANSACTION.
+ */
+ public static final String DELETE_GLOBAL_TRANSACTION = "delete from " + GLOBAL_TABLE_PLACEHOLD + " where xid = ?";
+
+ /**
+ * The constant QUERY_GLOBAL_TRANSACTION.
+ */
+ public static final String QUERY_GLOBAL_TRANSACTION = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where xid = ?";
+
+
+ /**
+ * The constant QUERY_GLOBAL_TRANSACTION_ID.
+ */
+ public static final String QUERY_GLOBAL_TRANSACTION_BY_ID = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where transaction_id = ?";
+
+
+ /**
+ * The constant QUERY_GLOBAL_TRANSACTION_BY_STATUS.
+ */
+ public static final String QUERY_GLOBAL_TRANSACTION_BY_STATUS = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD +
+ " where status in (" + PRAMETER_PLACEHOLD + ") order by gmt_modified limit ?";
+ /**
+ * The constant QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL.
+ */
+ public static final String QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where status in (" +
+ "0, 2, 3, 4, 5, 6, 7, 8, 10 ,12, 14) order by gmt_modified limit ?";
+
+ /**
+ * The constant QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE.
+ */
+ public static final String QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE = "select A.* from ( select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where status in (" +
+ "0, 2, 3, 4, 5, 6, 7, 8, 10 ,12, 14) order by gmt_modified ) A where ROWNUM <= ?" ;
+
+
+ /**
+ * The constant INSERT_BRANCH_TRANSACTION_MYSQL.
+ */
+ public static final String INSERT_BRANCH_TRANSACTION_MYSQL = "insert into " + BRANCH_TABLE_PLACEHOLD + "("+ ALL_BRANCH_COLUMNS +")" +
+ "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now())";
+
+ /**
+ * The constant INSERT_BRANCH_TRANSACTION_ORACLE.
+ */
+ public static final String INSERT_BRANCH_TRANSACTION_ORACLE = "insert into " + BRANCH_TABLE_PLACEHOLD + "("+ ALL_BRANCH_COLUMNS +")" +
+ "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)";
+
+ /**
+ * The constant UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL.
+ */
+ public static final String UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL = "update "+ BRANCH_TABLE_PLACEHOLD + " set status = ?, gmt_modified = now() where xid = ? and branch_id = ?";
+
+ /**
+ * The constant UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE.
+ */
+ public static final String UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE = "update "+ BRANCH_TABLE_PLACEHOLD + " set status = ?, gmt_modified = sysdate where xid = ? and branch_id = ?" ;
+
+ /**
+ * The constant DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID.
+ */
+ public static final String DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID = "delete from " + BRANCH_TABLE_PLACEHOLD + " where xid = ? and branch_id = ?";
+
+ /**
+ * The constant DELETE_BRANCH_TRANSACTION_BY_XID.
+ */
+ public static final String DELETE_BRANCH_TRANSACTION_BY_XID = "delete from " + BRANCH_TABLE_PLACEHOLD + " where xid = ?";
+
+ /**
+ * The constant QUREY_BRANCH_TRANSACTION.
+ */
+ public static final String QUREY_BRANCH_TRANSACTION = "select "+ALL_BRANCH_COLUMNS+" from " + BRANCH_TABLE_PLACEHOLD + " where xid = ?";
+
+ /**
+ * Get insert global transaction sql string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getInsertGlobalTransactionSQL(String globalTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return INSERT_GLOBAL_TRANSACTION_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return INSERT_GLOBAL_TRANSACTION_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get update global transaction status sql string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getUpdateGlobalTransactionStatusSQL(String globalTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get delete global transaction sql string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getDeleteGlobalTransactionSQL(String globalTable, String dbType){
+ return DELETE_GLOBAL_TRANSACTION.replace(GLOBAL_TABLE_PLACEHOLD, globalTable );
+ }
+
+ /**
+ * Get query global transaction sql string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getQueryGlobalTransactionSQL(String globalTable, String dbType){
+ return QUERY_GLOBAL_TRANSACTION.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }
+
+ /**
+ * Get query global transaction sql by transaction id string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getQueryGlobalTransactionSQLByTransactionId(String globalTable, String dbType){
+ return QUERY_GLOBAL_TRANSACTION_BY_ID.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }
+
+
+ /**
+ * Get query global transaction sql by status string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @param paramsPlaceHolder the params place holder
+ * @return the string
+ */
+ public static String getQueryGlobalTransactionSQLByStatus(String globalTable, String dbType, String paramsPlaceHolder){
+ return QUERY_GLOBAL_TRANSACTION_BY_STATUS.replace(GLOBAL_TABLE_PLACEHOLD, globalTable).replace(PRAMETER_PLACEHOLD, paramsPlaceHolder);
+ }
+
+ /**
+ * Get query global transaction for recovery sql string.
+ *
+ * @param globalTable the global table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getQueryGlobalTransactionForRecoverySQL(String globalTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get insert branch transaction sql string.
+ *
+ * @param branchTable the branch table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getInsertBranchTransactionSQL(String branchTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return INSERT_BRANCH_TRANSACTION_MYSQL.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return INSERT_BRANCH_TRANSACTION_ORACLE.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get update branch transaction status sql string.
+ *
+ * @param branchTable the branch table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getUpdateBranchTransactionStatusSQL(String branchTable, String dbType){
+ if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
+ || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
+ || DBType.H2.name().equalsIgnoreCase(dbType)){
+ return UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
+ return UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }else{
+ throw new NotSupportYetException("unknown dbType:" + dbType);
+ }
+ }
+
+ /**
+ * Get delete branch transaction by branch id sql string.
+ *
+ * @param branchTable the branch table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getDeleteBranchTransactionByBranchIdSQL(String branchTable, String dbType){
+ return DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }
+
+ /**
+ * Get delete branch transaction by x id string.
+ *
+ * @param branchTable the branch table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getDeleteBranchTransactionByXId(String branchTable, String dbType){
+ return DELETE_BRANCH_TRANSACTION_BY_XID.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }
+
+ /**
+ * Get qurey branch transaction string.
+ *
+ * @param branchTable the branch table
+ * @param dbType the db type
+ * @return the string
+ */
+ public static String getQureyBranchTransaction(String branchTable, String dbType){
+ return QUREY_BRANCH_TRANSACTION.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
+ }
+}
\ No newline at end of file
diff --git a/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore b/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore
new file mode 100644
index 00000000000..bd6ff3d994a
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore
@@ -0,0 +1 @@
+io.seata.core.store.db.LockStoreDataBaseDAO
\ No newline at end of file
diff --git a/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore b/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore
new file mode 100644
index 00000000000..f95309566f9
--- /dev/null
+++ b/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore
@@ -0,0 +1 @@
+io.seata.core.store.db.LogStoreDataBaseDAO
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java b/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
new file mode 100644
index 00000000000..d76a6c79dc4
--- /dev/null
+++ b/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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 org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import io.netty.buffer.ByteBuf;
+import static io.netty.buffer.Unpooled.buffer;
+
+/**
+ * RegisterTMRequest Test
+ *
+ * @author kaitithoma
+ * @author Danaykap
+ *
+ * @date 2019/05/13
+ *
+ */
+
+public class RegisterTMRequestTest {
+
+ 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);
+
+ /** 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/store/db/DataBaseLockStoreDAOTest.java b/core/src/test/java/io/seata/core/store/db/DataBaseLockStoreDAOTest.java
new file mode 100644
index 00000000000..eee248eb8cd
--- /dev/null
+++ b/core/src/test/java/io/seata/core/store/db/DataBaseLockStoreDAOTest.java
@@ -0,0 +1,300 @@
+/*
+ * 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.store.db;
+
+import io.seata.core.store.LockDO;
+import org.apache.commons.dbcp.BasicDataSource;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author zhangsen
+ * @data 2019/4/26
+ */
+public class DataBaseLockStoreDAOTest {
+
+ static LockStoreDataBaseDAO dataBaseLockStoreDAO = null;
+
+ static BasicDataSource dataSource = null;
+
+ @BeforeAll
+ public static void start(){
+ dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUrl("jdbc:h2:./db_store/lock");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+
+ dataBaseLockStoreDAO = new LockStoreDataBaseDAO(dataSource);
+ dataBaseLockStoreDAO.setDbType("h2");
+ dataBaseLockStoreDAO.setLockTable("lock_table");
+
+ prepareTable(dataSource);
+ }
+
+ private static void prepareTable(BasicDataSource dataSource) {
+ Connection conn = null;
+ try {
+ conn = dataSource.getConnection();
+ Statement s = conn.createStatement();
+ try {
+ s.execute("drop table lock_table");
+ } catch (Exception e) {
+ }
+ s.execute("CREATE TABLE lock_table ( xid varchar(96) , transaction_id long , branch_id long, resource_id varchar(32) ,table_name varchar(32) ,pk varchar(32) , row_key varchar(128) primary key not null, gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
+ System.out.println("create table lock_table success.");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ @Test
+ public void test_acquireLocks() throws SQLException {
+ List lockDOs = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-123:123");
+ lock.setTransactionId(123L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs.add(lock);
+ }
+
+ boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from lock_table where xid = 'abc-123:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+ } finally {
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
+
+ }
+
+
+ @Test
+ public void test_re_acquireLocks() throws SQLException {
+ List lockDOs = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-123:123");
+ lock.setTransactionId(123L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs.add(lock);
+ }
+
+ boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from lock_table where xid = 'abc-123:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+ } finally {
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ //lock again
+ Assertions.assertTrue(dataBaseLockStoreDAO.acquireLock(lockDOs));
+
+ Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
+
+ }
+
+ @Test
+ public void tes_unLocks() throws SQLException {
+ List lockDOs = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-456:123");
+ lock.setTransactionId(123L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs.add(lock);
+ }
+
+ boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from lock_table where xid = 'abc-456:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+ rs.close();
+
+ //unlock
+ Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
+
+ rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(false);
+ }else {
+ Assertions.assertTrue(true);
+ }
+
+ } finally {
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+
+ }
+
+
+ @Test
+ public void test_isLockable_can(){
+ List lockDOs = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-678:123");
+ lock.setTransactionId(123L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs.add(lock);
+ }
+
+ boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
+ Assertions.assertTrue(ret);
+
+ //unlock
+ Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
+ }
+
+ @Test
+ public void test_isLockable_cannot() throws SQLException {
+ List lockDOs = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-123:222");
+ lock.setTransactionId(222L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs.add(lock);
+ }
+
+ boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from lock_table where xid = 'abc-123:222' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+ } finally {
+ if(conn != null){
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ List lockDOs_2 = new ArrayList<>();
+ for(int i = 0; i < 3; i++){
+ LockDO lock = new LockDO();
+ lock.setResourceId("abc");
+ lock.setXid("abc-123:333");
+ lock.setTransactionId(333L);
+ lock.setBranchId((long) i);
+ lock.setRowKey("abc-"+i);
+ lock.setPk(String.valueOf(i));
+ lock.setTableName("t");
+ lockDOs_2.add(lock);
+ }
+
+ boolean ret2 = dataBaseLockStoreDAO.acquireLock(lockDOs_2);
+ Assertions.assertTrue(!ret2);
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java b/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java
new file mode 100644
index 00000000000..12aaf5259ea
--- /dev/null
+++ b/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java
@@ -0,0 +1,659 @@
+/*
+ * 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.store.db;
+
+import io.seata.common.util.CollectionUtils;
+import io.seata.core.store.BranchTransactionDO;
+import io.seata.core.store.GlobalTransactionDO;
+import org.apache.commons.dbcp.BasicDataSource;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Assertions;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+
+
+/**
+ * @author zhangsen
+ * @data 2019/4/26
+ */
+public class LogStoreDataBaseDAOTest {
+
+ static LogStoreDataBaseDAO logStoreDataBaseDAO = null;
+
+ static BasicDataSource dataSource = null;
+
+ @BeforeAll
+ public static void start(){
+ dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUrl("jdbc:h2:./db_store/log");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+
+ logStoreDataBaseDAO = new LogStoreDataBaseDAO(dataSource);
+ logStoreDataBaseDAO.setDbType("h2");
+ logStoreDataBaseDAO.setGlobalTable("global_table");
+ logStoreDataBaseDAO.setBrachTable("branch_table");
+
+ prepareTable(dataSource);
+ }
+
+ private static void prepareTable(BasicDataSource dataSource) {
+ Connection conn = null;
+ try {
+ conn = dataSource.getConnection();
+ Statement s = conn.createStatement();
+ try {
+ s.execute("drop table global_table");
+ } catch (Exception e) {
+ }
+// xid, transaction_id, status, application_id, transaction_service_group, transaction_name, timeout, begin_time, application_data, gmt_create, gmt_modified
+ s.execute("CREATE TABLE global_table ( xid varchar(96) primary key, transaction_id long , STATUS int, application_id varchar(32), transaction_service_group varchar(32) ,transaction_name varchar(32) ,timeout int, begin_time long, application_data varchar(500), gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
+ System.out.println("create table global_table success.");
+
+ try {
+ s.execute("drop table branch_table");
+ } catch (Exception e) {
+ }
+// xid, transaction_id, branch_id, resource_group_id, resource_id, lock_key, branch_type, status, client_id, application_data, gmt_create, gmt_modified
+ s.execute("CREATE TABLE branch_table ( xid varchar(96), transaction_id long , branch_id long primary key, resource_group_id varchar(32), resource_id varchar(32) ,lock_key varchar(64) ,branch_type varchar(32) , status int , client_id varchar(128), application_data varchar(500), gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
+ System.out.println("create table branch_table success.");
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ @Test
+ public void queryGlobalTransactionDO_by_xid() throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:978786");
+ globalTransactionDO.setApplicationData("abc=87867978");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(143546567);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+
+
+ GlobalTransactionDO globalTransactionDO_db = logStoreDataBaseDAO.queryGlobalTransactionDO("abc-123:978786");
+ Assertions.assertNotNull(globalTransactionDO_db);
+
+ Assertions.assertEquals(globalTransactionDO_db.getBeginTime(), globalTransactionDO_db.getBeginTime());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionName(), globalTransactionDO_db.getTransactionName());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionId(), globalTransactionDO_db.getTransactionId());
+ Assertions.assertEquals(globalTransactionDO_db.getStatus(), globalTransactionDO_db.getStatus());
+ Assertions.assertEquals(globalTransactionDO_db.getTimeout(), globalTransactionDO_db.getTimeout());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionServiceGroup(), globalTransactionDO_db.getTransactionServiceGroup());
+ Assertions.assertEquals(globalTransactionDO_db.getApplicationId(), globalTransactionDO_db.getApplicationId());
+ Assertions.assertNotNull(globalTransactionDO_db.getGmtCreate());
+ Assertions.assertNotNull(globalTransactionDO_db.getGmtModified());
+
+
+ String delSql = "delete from global_table where xid= 'abc-123:978786'";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ //delete
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+ }
+
+ @Test
+ public void queryGlobalTransactionDO_by_transaction_id() throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:676787978");
+ globalTransactionDO.setApplicationData("abc=234356");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(867978970);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+
+ GlobalTransactionDO globalTransactionDO_db = logStoreDataBaseDAO.queryGlobalTransactionDO(867978970L);
+ Assertions.assertNotNull(globalTransactionDO_db);
+
+ Assertions.assertEquals(globalTransactionDO_db.getXid(), globalTransactionDO_db.getXid());
+ Assertions.assertEquals(globalTransactionDO_db.getBeginTime(), globalTransactionDO_db.getBeginTime());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionName(), globalTransactionDO_db.getTransactionName());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionId(), globalTransactionDO_db.getTransactionId());
+ Assertions.assertEquals(globalTransactionDO_db.getStatus(), globalTransactionDO_db.getStatus());
+ Assertions.assertEquals(globalTransactionDO_db.getTimeout(), globalTransactionDO_db.getTimeout());
+ Assertions.assertEquals(globalTransactionDO_db.getTransactionServiceGroup(), globalTransactionDO_db.getTransactionServiceGroup());
+ Assertions.assertEquals(globalTransactionDO_db.getApplicationId(), globalTransactionDO_db.getApplicationId());
+ Assertions.assertNotNull(globalTransactionDO_db.getGmtCreate());
+ Assertions.assertNotNull(globalTransactionDO_db.getGmtModified());
+
+ String delSql = "delete from global_table where xid= 'abc-123:978786'";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ //delete
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+ }
+
+ @Test
+ public void queryGlobalTransactionDO_by_statuses() throws SQLException {
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:1267");
+ globalTransactionDO.setApplicationData("abc=234356");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(867978970);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ Assertions.assertTrue(logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO));
+ }
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:6978");
+ globalTransactionDO.setApplicationData("abc=87867978");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(143546567);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(2);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:5657");
+ globalTransactionDO.setApplicationData("abc=5454");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(12345);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+
+ List globalTransactionDOs = logStoreDataBaseDAO.queryGlobalTransactionDO(new int[]{1}, 10);
+ Assertions.assertNotNull(globalTransactionDOs);
+ Assertions.assertEquals(2, globalTransactionDOs.size());
+
+ if("abc-123:5657".equals(globalTransactionDOs.get(0).getXid()) && "abc-123:1267".equals(globalTransactionDOs.get(1).getXid())){
+ Assertions.assertTrue(true);
+ }else if("abc-123:5657".equals(globalTransactionDOs.get(1).getXid()) && "abc-123:1267".equals(globalTransactionDOs.get(0).getXid())){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+
+ String delSql = "delete from global_table where xid in ('abc-123:1267', 'abc-123:6978', 'abc-123:5657')";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+ @Test
+ public void queryGlobalTransactionDO_by_statuses_limit() throws SQLException {
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:1267");
+ globalTransactionDO.setApplicationData("abc=234356");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(867978970);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ Assertions.assertTrue(logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO));
+ }
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:6978");
+ globalTransactionDO.setApplicationData("abc=87867978");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(143546567);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(2);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+ {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:5657");
+ globalTransactionDO.setApplicationData("abc=5454");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(12345);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+
+ List globalTransactionDOs = logStoreDataBaseDAO.queryGlobalTransactionDO(new int[]{1}, 1);
+ Assertions.assertNotNull(globalTransactionDOs);
+ Assertions.assertEquals(1, globalTransactionDOs.size());
+
+ if("abc-123:1267".equals(globalTransactionDOs.get(0).getXid())){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+
+ String delSql = "delete from global_table where xid in ('abc-123:1267', 'abc-123:6978', 'abc-123:5657')";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+ }
+
+ @Test
+ public void insertGlobalTransactionDO() throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:333");
+ globalTransactionDO.setApplicationData("abc=5454");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(12345);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from global_table where xid= 'abc-123:333'";
+ String delSql = "delete from global_table where xid= 'abc-123:333'";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else{
+ Assertions.assertTrue(false);
+ }
+
+ conn.createStatement().execute(delSql);
+
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+ @Test
+ public void updateGlobalTransactionDO() throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:222");
+ globalTransactionDO.setApplicationData("abc=5454");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(12345);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+
+ String sql = "select * from global_table where xid= 'abc-123:222'";
+ String delSql = "delete from global_table where xid= 'abc-123:222'";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ Assertions.assertEquals(1, rs.getInt("status"));
+ }else{
+ Assertions.assertTrue(false);
+ }
+ rs.close();
+
+ //update
+ globalTransactionDO.setStatus(2);
+ Assertions.assertTrue(logStoreDataBaseDAO.updateGlobalTransactionDO(globalTransactionDO));
+
+ rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ Assertions.assertEquals(2, rs.getInt("status"));
+ }else{
+ Assertions.assertTrue(false);
+ }
+ rs.close();
+
+ //delete
+ conn.createStatement().execute(delSql);
+
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+ }
+
+ @Test
+ public void deleteGlobalTransactionDO() throws SQLException {
+ GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
+ globalTransactionDO.setXid("abc-123:555");
+ globalTransactionDO.setApplicationData("abc=5454");
+ globalTransactionDO.setTransactionServiceGroup("abc");
+ globalTransactionDO.setTransactionName("test");
+ globalTransactionDO.setTransactionId(12345);
+ globalTransactionDO.setTimeout(20);
+ globalTransactionDO.setBeginTime(System.currentTimeMillis());
+ globalTransactionDO.setApplicationId("test");
+ globalTransactionDO.setStatus(1);
+
+ boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
+ Assertions.assertTrue(ret);
+
+ //delete
+ Assertions.assertTrue(logStoreDataBaseDAO.deleteGlobalTransactionDO(globalTransactionDO));
+
+ //check
+
+ String sql = "select * from global_table where xid= 'abc-123:555'";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(false);
+ }else{
+ Assertions.assertTrue(true);
+ }
+ rs.close();
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+ @Test
+ public void queryBranchTransactionDO() throws SQLException {
+ {
+ //creata data for test
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceId("qqqq");
+ branchTransactionDO.setXid("abc-123:6789");
+ branchTransactionDO.setTransactionId(24234235);
+ branchTransactionDO.setBranchId(345465676);
+ branchTransactionDO.setBranchType("TCC");
+ branchTransactionDO.setResourceGroupId("abc");
+ branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
+ branchTransactionDO.setResourceGroupId("a");
+ branchTransactionDO.setClientId("1.1.1.1");
+ branchTransactionDO.setStatus(1);
+ branchTransactionDO.setApplicationData("abc=123");
+ branchTransactionDO.setResourceGroupId("test");
+
+ boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+ {
+ //creata data for test
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceId("qqqq");
+ branchTransactionDO.setXid("abc-123:6789");
+ branchTransactionDO.setTransactionId(24234235);
+ branchTransactionDO.setBranchId(78563453);
+ branchTransactionDO.setBranchType("TCC");
+ branchTransactionDO.setResourceGroupId("abc");
+ branchTransactionDO.setLockKey("t:6;t2:7");
+ branchTransactionDO.setResourceGroupId("a");
+ branchTransactionDO.setClientId("1.1.1.1");
+ branchTransactionDO.setStatus(1);
+ branchTransactionDO.setApplicationData("abc=123");
+ branchTransactionDO.setResourceGroupId("test");
+
+ boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
+ Assertions.assertTrue(ret);
+ }
+
+ List rets = logStoreDataBaseDAO.queryBranchTransactionDO("abc-123:6789");
+ Assertions.assertTrue(CollectionUtils.isNotEmpty(rets));
+ Assertions.assertEquals(2, rets.size());
+
+ if(78563453 == rets.get(0).getBranchId() && 345465676 == rets.get(1).getBranchId()){
+ Assertions.assertTrue(true);
+ }else if(78563453 == rets.get(1).getBranchId() && 345465676 == rets.get(0).getBranchId()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+
+ String delSql = "delete from branch_table where xid= 'abc-123:6789' ";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+
+ conn.createStatement().execute(delSql);
+
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+ @Test
+ public void insertBranchTransactionDO() throws SQLException {
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceId("qqqq");
+ branchTransactionDO.setXid("abc-123:7777");
+ branchTransactionDO.setTransactionId(1285343);
+ branchTransactionDO.setBranchId(1234508);
+ branchTransactionDO.setBranchType("TCC");
+ branchTransactionDO.setResourceGroupId("abc");
+ branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
+ branchTransactionDO.setResourceGroupId("a");
+ branchTransactionDO.setClientId("1.1.1.1");
+ branchTransactionDO.setStatus(1);
+ branchTransactionDO.setApplicationData("abc=123");
+ branchTransactionDO.setResourceGroupId("test");
+
+ boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
+ Assertions.assertTrue(ret);
+
+
+ String sql = "select * from branch_table where xid= 'abc-123:7777' and branch_id = 1234508";
+ String delSql = "delete from branch_table where xid= 'abc-123:7777' and branch_id = 1234508";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+
+ }
+
+ @Test
+ public void updateBranchTransactionDO() throws SQLException {
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceId("qqqq");
+ branchTransactionDO.setXid("abc-123:8888");
+ branchTransactionDO.setTransactionId(1285343);
+ branchTransactionDO.setBranchId(343434318);
+ branchTransactionDO.setBranchType("TCC");
+ branchTransactionDO.setResourceGroupId("abc");
+ branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
+ branchTransactionDO.setResourceGroupId("a");
+ branchTransactionDO.setClientId("1.1.1.1");
+ branchTransactionDO.setStatus(1);
+ branchTransactionDO.setApplicationData("abc=123");
+ branchTransactionDO.setResourceGroupId("test");
+
+ boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
+ Assertions.assertTrue(ret);
+
+ branchTransactionDO.setStatus(3);
+ Assertions.assertTrue(logStoreDataBaseDAO.updateBranchTransactionDO(branchTransactionDO));
+
+ String sql = "select * from branch_table where xid= 'abc-123:8888' and branch_id = 343434318";
+ String delSql = "delete from branch_table where xid= 'abc-123:8888' and branch_id = 343434318";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ Assertions.assertEquals(3, rs.getInt("status"));
+ }else {
+ Assertions.assertTrue(false);
+ }
+
+ conn.createStatement().execute(delSql);
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+ @Test
+ public void deleteBranchTransactionDO() throws SQLException {
+ BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
+ branchTransactionDO.setResourceId("qqqq");
+ branchTransactionDO.setXid("abc-123:9999");
+ branchTransactionDO.setTransactionId(1285343);
+ branchTransactionDO.setBranchId(34567798);
+ branchTransactionDO.setBranchType("TCC");
+ branchTransactionDO.setResourceGroupId("abc");
+ branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
+ branchTransactionDO.setResourceGroupId("a");
+ branchTransactionDO.setClientId("1.1.1.1");
+ branchTransactionDO.setStatus(1);
+ branchTransactionDO.setApplicationData("abc=123");
+ branchTransactionDO.setResourceGroupId("test");
+
+ boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
+ Assertions.assertTrue(ret);
+
+
+ String sql = "select * from branch_table where xid= 'abc-123:9999' and branch_id = 34567798";
+ String delSql = "delete from branch_table where xid= 'abc-123:9999' and branch_id = 34567798";
+ Connection conn = null;
+ try{
+ conn = dataSource.getConnection();
+
+ ResultSet rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(true);
+ }else {
+ Assertions.assertTrue(false);
+ }
+ rs.close();
+
+ //delete
+ logStoreDataBaseDAO.deleteBranchTransactionDO(branchTransactionDO);
+
+ rs = conn.createStatement().executeQuery(sql);
+ if(rs.next()){
+ Assertions.assertTrue(false);
+ }else {
+ Assertions.assertTrue(true);
+ }
+ rs.close();
+
+ }finally {
+ if(conn != null){
+ conn.close();
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java b/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java
new file mode 100644
index 00000000000..663234beea1
--- /dev/null
+++ b/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.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.config;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * @author Geng Zhang
+ */
+class ConfigurationFactoryTest {
+
+ @Test
+ void getInstance() {
+ Configuration configuration = ConfigurationFactory.getInstance();
+ // check singleton
+ Assertions.assertEquals(configuration, ConfigurationFactory.getInstance());
+ }
+}
\ No newline at end of file
diff --git a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
index 8687246b90f..ceedb26bd64 100644
--- a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
+++ b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
@@ -16,7 +16,6 @@
package io.seata.discovery.registry.eureka;
import io.seata.common.loader.LoadLevel;
-import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryProvider;
diff --git a/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java b/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
index 1acd0db7f7e..d201ce29c22 100644
--- a/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
+++ b/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
@@ -16,7 +16,6 @@
package io.seata.discovery.registry.nacos;
import io.seata.common.loader.LoadLevel;
-import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryProvider;
diff --git a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
index 4585a45b092..10bd29dcae9 100644
--- a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
+++ b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
@@ -18,8 +18,6 @@
import io.seata.common.loader.LoadLevel;
import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
-import io.seata.discovery.registry.RegistryProvider;
-import io.seata.discovery.registry.RegistryService;
/**
* @author xingfudeshi@gmail.com
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 9c1d87a8810..1ea76541b20 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
@@ -34,7 +34,6 @@
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
-import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryService;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
diff --git a/pom.xml b/pom.xml
index e3628dda535..d657ed812a4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,7 +82,7 @@
- 0.5.2
+ 0.6.0
1.8
@@ -107,6 +107,7 @@
2.23.4
3.12.2
1.4.2
+
@@ -142,7 +143,6 @@
test
-
diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml
index 8ab21440bb4..3b1a0435f45 100644
--- a/rm-datasource/pom.xml
+++ b/rm-datasource/pom.xml
@@ -48,6 +48,17 @@
caffeine
+
+ commons-dbcp
+ commons-dbcp
+ test
+
+
+ com.h2database
+ h2
+ test
+
+
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 b835dc354ab..40adc924fa6 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
@@ -37,7 +37,6 @@
import java.util.Calendar;
import java.util.List;
-import io.seata.rm.datasource.sql.struct.Null;
import io.seata.rm.datasource.sql.struct.Null;
/**
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java b/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
index f6076f88204..dd5f1baa2c3 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
@@ -178,7 +178,7 @@ private void doBranchCommits() {
int maxSize = xids.size() > branchIds.size() ? xids.size() : branchIds.size();
if(maxSize == UNDOLOG_DELETE_LIMIT_SIZE){
try {
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, UNDOLOG_DELETE_LIMIT_SIZE, conn);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, conn);
} catch (Exception ex) {
LOGGER.warn("Failed to batch delete undo log [" + branchIds + "/" + xids + "]", ex);
}
@@ -192,7 +192,7 @@ private void doBranchCommits() {
}
try {
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, UNDOLOG_DELETE_LIMIT_SIZE, conn);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, conn);
}catch (Exception ex) {
LOGGER.warn("Failed to batch delete undo log [" + branchIds + "/" + xids + "]", ex);
}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
index 5279ad772d7..492d59be5f2 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
@@ -20,8 +20,6 @@
import java.sql.SQLException;
import java.util.ArrayList;
-import io.seata.rm.datasource.exec.ExecuteTemplate;
-import io.seata.rm.datasource.exec.StatementCallback;
import io.seata.rm.datasource.exec.ExecuteTemplate;
import io.seata.rm.datasource.exec.StatementCallback;
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 e0b1eb7ab68..955fc81c058 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
@@ -19,8 +19,6 @@
import java.sql.SQLException;
import java.sql.Statement;
-import io.seata.rm.datasource.exec.ExecuteTemplate;
-import io.seata.rm.datasource.exec.StatementCallback;
import io.seata.rm.datasource.exec.ExecuteTemplate;
import io.seata.rm.datasource.exec.StatementCallback;
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 6a3f3f848b5..26507eb74f3 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
@@ -29,8 +29,6 @@
import io.seata.rm.datasource.sql.SQLRecognizer;
import io.seata.rm.datasource.sql.struct.TableMeta;
import io.seata.rm.datasource.sql.struct.TableRecords;
-import io.seata.rm.datasource.undo.KeywordChecker;
-import io.seata.rm.datasource.undo.KeywordCheckerFactory;
import io.seata.rm.datasource.undo.KeywordChecker;
import io.seata.rm.datasource.undo.KeywordCheckerFactory;
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
index be6537bfe12..26d87cd1d38 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
@@ -17,7 +17,6 @@
import java.util.ArrayList;
-import io.seata.rm.datasource.ParametersHolder;
import io.seata.rm.datasource.ParametersHolder;
/**
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
index 779da87c8d1..36f14f97203 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
@@ -15,16 +15,25 @@
*/
package io.seata.rm.datasource.undo;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-
+import com.alibaba.fastjson.JSON;
+import io.seata.common.util.StringUtils;
+import io.seata.config.ConfigurationFactory;
+import io.seata.core.constants.ConfigurationKeys;
import io.seata.rm.datasource.DataCompareUtils;
import io.seata.rm.datasource.sql.struct.Field;
import io.seata.rm.datasource.sql.struct.KeyType;
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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
/**
* The type Abstract undo executor.
@@ -34,6 +43,24 @@
*/
public abstract class AbstractUndoExecutor {
+ /**
+ * Logger for AbstractUndoExecutor
+ **/
+ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractUndoExecutor.class);
+
+ /**
+ * template of check sql
+ *
+ * TODO support multiple primary key
+ */
+ private static final String CHECK_SQL_TEMPLATE = "SELECT * FROM %s WHERE %s in (%s)";
+
+ /**
+ * Switch of undo data validation
+ */
+ public static final boolean IS_UNDO_DATA_VALIDATION_ENABLE = ConfigurationFactory.getInstance()
+ .getBoolean(ConfigurationKeys.TRANSACTION_UNOD_DATA_VALIDATION, true);
+
/**
* The Sql undo log.
*/
@@ -72,11 +99,10 @@ public SQLUndoLog getSqlUndoLog() {
*/
public void executeOn(Connection conn) throws SQLException {
- // no need undo if the before data snapshot is equivalent to the after data snapshot.
- if (DataCompareUtils.isRecordsEquals(sqlUndoLog.getBeforeImage(), sqlUndoLog.getAfterImage())) {
+ if (IS_UNDO_DATA_VALIDATION_ENABLE && !dataValidationAndGoOn(conn)) {
return;
}
- dataValidation(conn);
+
try {
String undoSQL = buildUndoSQL();
@@ -145,9 +171,125 @@ protected void undoPrepare(PreparedStatement undoPST, ArrayList undoValue
* Data validation.
*
* @param conn the conn
- * @throws SQLException the sql exception
+ * @return return true if data validation is ok and need continue undo, and return false if no need continue undo.
+ * @throws SQLException the sql exception such as has dirty data
*/
- protected void dataValidation(Connection conn) throws SQLException {
+ protected boolean dataValidationAndGoOn(Connection conn) throws SQLException {
+
+ TableRecords beforeRecords = sqlUndoLog.getBeforeImage();
+ TableRecords afterRecords = sqlUndoLog.getAfterImage();
+
+ // Compare current data with before data
+ // No need undo if the before data snapshot is equivalent to the after data snapshot.
+ if (DataCompareUtils.isRecordsEquals(beforeRecords, afterRecords)) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Stop rollback because there is no data change " +
+ "between the before data snapshot and the after data snapshot.");
+ }
+ // no need continue undo.
+ return false;
+ }
+
// Validate if data is dirty.
+ TableRecords currentRecords = queryCurrentRecords(conn);
+ // compare with current data and after image.
+ if (!DataCompareUtils.isRecordsEquals(afterRecords, currentRecords)) {
+
+ // If current data is not equivalent to the after data, then compare the current data with the before
+ // data, too. No need continue to undo if current data is equivalent to the before data snapshot
+ if (DataCompareUtils.isRecordsEquals(beforeRecords, currentRecords)) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Stop rollback because there is no data change " +
+ "between the before data snapshot and the current data snapshot.");
+ }
+ // no need continue undo.
+ return false;
+ } else {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("check dirty datas failed, old and new data are not equal," +
+ "tableName:[" + sqlUndoLog.getTableName() + "]," +
+ "oldRows:[" + JSON.toJSONString(afterRecords.getRows()) + "]," +
+ "newRows:[" + JSON.toJSONString(currentRecords.getRows()) + "].");
+ }
+ throw new SQLException("Has dirty records when undo.");
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Query current records.
+ *
+ * @param conn the conn
+ * @return the table records
+ * @throws SQLException the sql exception
+ */
+ protected TableRecords queryCurrentRecords(Connection conn) throws SQLException {
+ TableRecords undoRecords = getUndoRows();
+ TableMeta tableMeta = undoRecords.getTableMeta();
+ String pkName = tableMeta.getPkName();
+ int pkType = tableMeta.getColumnMeta(pkName).getDataType();
+
+ // pares pk values
+ Object[] pkValues = parsePkValues(getUndoRows());
+ if (pkValues.length == 0) {
+ return TableRecords.empty(tableMeta);
+ }
+ StringBuffer replace = new StringBuffer();
+ for (int i = 0; i < pkValues.length; i++) {
+ replace.append("?,");
+ }
+ // build check sql
+ String checkSQL = String.format(CHECK_SQL_TEMPLATE, sqlUndoLog.getTableName(), pkName,
+ replace.substring(0, replace.length() - 1));
+
+ PreparedStatement statement = null;
+ ResultSet checkSet = null;
+ TableRecords currentRecords;
+ try {
+ statement = conn.prepareStatement(checkSQL);
+ for (int i = 1; i <= pkValues.length; i++) {
+ statement.setObject(i, pkValues[i - 1], pkType);
+ }
+ checkSet = statement.executeQuery();
+ currentRecords = TableRecords.buildRecords(tableMeta, checkSet);
+ } finally {
+ if (checkSet != null) {
+ try {
+ checkSet.close();
+ } catch (Exception e) {
+ }
+ }
+ if (statement != null) {
+ try {
+ statement.close();
+ } catch (Exception e) {
+ }
+ }
+ }
+ return currentRecords;
+ }
+
+ /**
+ * Parse pk values object [ ].
+ *
+ * @param records the records
+ * @return the object [ ]
+ */
+ protected Object[] parsePkValues(TableRecords records) {
+ String pkName = records.getTableMeta().getPkName();
+ List undoRows = records.getRows();
+ Object[] pkValues = new Object[undoRows.size()];
+ for (int i = 0; i < undoRows.size(); i++) {
+ List fields = undoRows.get(i).getFields();
+ if (fields != null) {
+ for (Field field : fields) {
+ if (StringUtils.equalsIgnoreCase(pkName, field.getName())) {
+ pkValues[i] = field.getValue();
+ }
+ }
+ }
+ }
+ return pkValues;
}
}
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 ab278f2e71f..deadf563778 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
@@ -18,7 +18,6 @@
import com.alibaba.druid.util.JdbcConstants;
import io.seata.common.exception.NotSupportYetException;
import io.seata.common.util.BlobUtils;
-import io.seata.common.util.StringUtils;
import io.seata.core.exception.TransactionException;
import io.seata.rm.datasource.ConnectionContext;
import io.seata.rm.datasource.ConnectionProxy;
@@ -161,7 +160,7 @@ public static void undo(DataSourceProxy dataSourceProxy, String xid, long branch
}
Blob b = rs.getBlob("rollback_info");
- String rollbackInfo = StringUtils.blob2string(b);
+ String rollbackInfo = BlobUtils.blob2string(b);
BranchUndoLog branchUndoLog = UndoLogParserFactory.getInstance().decode(rollbackInfo);
for (SQLUndoLog sqlUndoLog : branchUndoLog.getSqlUndoLogs()) {
@@ -234,13 +233,12 @@ public static void undo(DataSourceProxy dataSourceProxy, String xid, long branch
*
* @param xids
* @param branchIds
- * @param limitSize
* @param conn
*/
- public static void batchDeleteUndoLog(Set xids, Set branchIds, int limitSize, Connection conn) throws SQLException {
+ public static void batchDeleteUndoLog(Set xids, Set branchIds, Connection conn) throws SQLException {
int xidSize = xids.size();
int branchIdSize = branchIds.size();
- String batchDeleteSql = toBatchDeleteUndoLogSql(xidSize, branchIdSize,limitSize);
+ String batchDeleteSql = toBatchDeleteUndoLogSql(xidSize, branchIdSize);
PreparedStatement deletePST = null;
try {
deletePST = conn.prepareStatement(batchDeleteSql);
@@ -268,15 +266,14 @@ public static void batchDeleteUndoLog(Set xids, Set branchIds, int
}
- protected static String toBatchDeleteUndoLogSql(int xidSize, int branchIdSize,int limitSize) {
+ protected static String toBatchDeleteUndoLogSql(int xidSize, int branchIdSize) {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("DELETE FROM ")
.append(UNDO_LOG_TABLE_NAME)
.append(" WHERE branch_id IN ");
- appendInParam(xidSize, sqlBuilder);
- sqlBuilder.append(" AND xid IN ");
appendInParam(branchIdSize, sqlBuilder);
- sqlBuilder.append(" LIMIT ").append(limitSize);
+ sqlBuilder.append(" AND xid IN ");
+ appendInParam(xidSize, sqlBuilder);
return sqlBuilder.toString();
}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
new file mode 100644
index 00000000000..0d79fa178d0
--- /dev/null
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
@@ -0,0 +1,316 @@
+/*
+ * 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.rm.datasource.sql.SQLType;
+import io.seata.rm.datasource.sql.struct.ColumnMeta;
+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 org.apache.commons.dbcp.BasicDataSource;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Geng Zhang
+ */
+public class AbstractUndoExecutorTest extends BaseExecutorTest {
+
+ static BasicDataSource dataSource = null;
+
+ static Connection connection = null;
+
+ static TableMeta tableMeta = null;
+
+ @BeforeAll
+ public static void start() throws SQLException {
+ dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("org.h2.Driver");
+ dataSource.setUrl("jdbc:h2:./db_store/test_undo");
+ dataSource.setUsername("sa");
+ dataSource.setPassword("");
+
+ connection = dataSource.getConnection();
+
+ tableMeta = mockTableMeta();
+ }
+
+ @AfterAll
+ public static void stop() {
+ if (connection != null) {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ }
+ }
+ if (dataSource != null) {
+ try {
+ dataSource.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+
+ @BeforeEach
+ private void prepareTable() {
+ execSQL("DROP TABLE table_name");
+ execSQL("CREATE TABLE table_name ( `id` int(8), `name` varchar(64), PRIMARY KEY (`id`))");
+ }
+
+ @Test
+ public void dataValidationUpdate() throws SQLException {
+ execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
+ execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
+
+ TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ execSQL("update table_name set name = 'xxx' where id in (12345, 12346);");
+
+ TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ SQLUndoLog sqlUndoLog = new SQLUndoLog();
+ sqlUndoLog.setSqlType(SQLType.UPDATE);
+ sqlUndoLog.setTableMeta(tableMeta);
+ sqlUndoLog.setTableName("table_name");
+ sqlUndoLog.setBeforeImage(beforeImage);
+ sqlUndoLog.setAfterImage(afterImage);
+
+ TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, false);
+
+ // case1: normal case before:aaa -> after:xxx -> current:xxx
+ Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
+
+ // case2: dirty data before:aaa -> after:xxx -> current:yyy
+ execSQL("update table_name set name = 'yyy' where id in (12345, 12346);");
+ try {
+ spy.dataValidationAndGoOn(connection);
+ Assertions.fail();
+ } catch (Exception e) {
+ Assertions.assertTrue(e instanceof SQLException);
+ }
+
+ // case 3: before == current before:aaa -> after:xxx -> current:aaa
+ execSQL("update table_name set name = 'aaa' where id in (12345, 12346);");
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+
+ // case 4: before == after before:aaa -> after:aaa
+ afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+ sqlUndoLog.setAfterImage(afterImage);
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+ }
+
+ @Test
+ public void dataValidationInsert() throws SQLException {
+ TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
+ execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
+
+ TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ SQLUndoLog sqlUndoLog = new SQLUndoLog();
+ sqlUndoLog.setSqlType(SQLType.INSERT);
+ sqlUndoLog.setTableMeta(tableMeta);
+ sqlUndoLog.setTableName("table_name");
+ sqlUndoLog.setBeforeImage(beforeImage);
+ sqlUndoLog.setAfterImage(afterImage);
+
+ TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, false);
+
+ // case1: normal case before:0 -> after:2 -> current:2
+ Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
+
+ // case2: dirty data before:0 -> after:2 -> current:2'
+ execSQL("update table_name set name = 'yyy' where id in (12345, 12346);");
+ try {
+ Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
+ Assertions.fail();
+ } catch (Exception e) {
+ Assertions.assertTrue(e instanceof SQLException);
+ }
+
+ // case3: before == current before:0 -> after:2 -> current:0
+ execSQL("delete from table_name where id in (12345, 12346);");
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+
+ // case 4: before == after before:0 -> after:0
+ afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+ sqlUndoLog.setAfterImage(afterImage);
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+ }
+
+ @Test
+ public void dataValidationDelete() throws SQLException {
+ execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
+ execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
+
+ TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ execSQL("delete from table_name where id in (12345, 12346);");
+
+ TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+
+ SQLUndoLog sqlUndoLog = new SQLUndoLog();
+ sqlUndoLog.setSqlType(SQLType.INSERT);
+ sqlUndoLog.setTableMeta(tableMeta);
+ sqlUndoLog.setTableName("table_name");
+ sqlUndoLog.setBeforeImage(beforeImage);
+ sqlUndoLog.setAfterImage(afterImage);
+
+ TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, true);
+
+ // case1: normal case before:2 -> after:0 -> current:0
+ Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
+
+ // case2: dirty data before:2 -> after:0 -> current:1
+ execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
+ try {
+ Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
+ Assertions.fail();
+ } catch (Exception e) {
+ Assertions.assertTrue(e instanceof SQLException);
+ }
+
+ // case3: before == current before:2 -> after:0 -> current:2
+ execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+
+ // case 4: before == after before:2 -> after:2
+ afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
+ sqlUndoLog.setAfterImage(afterImage);
+ Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
+ }
+
+ @Test
+ public void testParsePK() {
+ TableMeta tableMeta = Mockito.mock(TableMeta.class);
+ Mockito.when(tableMeta.getPkName()).thenReturn("id");
+ Mockito.when(tableMeta.getTableName()).thenReturn("table_name");
+
+ TableRecords beforeImage = new TableRecords();
+ beforeImage.setTableName("table_name");
+ beforeImage.setTableMeta(tableMeta);
+
+ List beforeRows = new ArrayList<>();
+ Row row0 = new Row();
+ Field field01 = addField(row0, "id", 1, "12345");
+ Field field02 = addField(row0, "age", 1, "2");
+ beforeRows.add(row0);
+ Row row1 = new Row();
+ Field field11 = addField(row1, "id", 1, "12346");
+ Field field12 = addField(row1, "age", 1, "2");
+ beforeRows.add(row1);
+ beforeImage.setRows(beforeRows);
+
+ SQLUndoLog sqlUndoLog = new SQLUndoLog();
+ sqlUndoLog.setSqlType(SQLType.UPDATE);
+ sqlUndoLog.setTableMeta(tableMeta);
+ sqlUndoLog.setTableName("table_name");
+ sqlUndoLog.setBeforeImage(beforeImage);
+ sqlUndoLog.setAfterImage(null);
+
+ TestUndoExecutor executor = new TestUndoExecutor(sqlUndoLog, true);
+ Object[] pkValues = executor.parsePkValues(beforeImage);
+ Assertions.assertEquals(2, pkValues.length);
+ }
+
+
+ private static TableMeta mockTableMeta() {
+ TableMeta tableMeta = Mockito.mock(TableMeta.class);
+ Mockito.when(tableMeta.getPkName()).thenReturn("ID");
+ Mockito.when(tableMeta.getTableName()).thenReturn("table_name");
+ ColumnMeta meta0 = Mockito.mock(ColumnMeta.class);
+ Mockito.when(meta0.getDataType()).thenReturn(Types.INTEGER);
+ Mockito.when(meta0.getColumnName()).thenReturn("ID");
+ Mockito.when(tableMeta.getColumnMeta("ID")).thenReturn(meta0);
+ ColumnMeta meta1 = Mockito.mock(ColumnMeta.class);
+ Mockito.when(meta1.getDataType()).thenReturn(Types.VARCHAR);
+ Mockito.when(meta1.getColumnName()).thenReturn("NAME");
+ Mockito.when(tableMeta.getColumnMeta("NAME")).thenReturn(meta1);
+ return tableMeta;
+ }
+
+ private void execSQL(String sql) {
+ Statement s = null;
+ try {
+ s = connection.createStatement();
+ s.execute(sql);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ private TableRecords execQuery(TableMeta tableMeta, String sql) throws SQLException {
+ Statement s = null;
+ ResultSet set = null;
+ try {
+ s = connection.createStatement();
+ set = s.executeQuery(sql);
+ return TableRecords.buildRecords(tableMeta, set);
+ } finally {
+ if (set != null) {
+ try {
+ set.close();
+ } catch (Exception e) {
+ }
+ }
+ if (s != null) {
+ try {
+ s.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+}
+
+class TestUndoExecutor extends AbstractUndoExecutor {
+ private boolean isDelete;
+ public TestUndoExecutor(SQLUndoLog sqlUndoLog, boolean isDelete) {
+ super(sqlUndoLog);
+ this.isDelete = isDelete;
+ }
+
+ @Override
+ protected String buildUndoSQL() {
+ return null;
+ }
+
+ @Override
+ protected TableRecords getUndoRows() {
+ return isDelete ? sqlUndoLog.getBeforeImage() : sqlUndoLog.getAfterImage();
+ }
+}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
index eb7a0324bb2..ae1174c8c5c 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
@@ -59,6 +59,7 @@
import io.seata.rm.datasource.sql.struct.TableRecords;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
/**
* The type Undo executor test.
@@ -88,7 +89,7 @@ public void testField() {
* Test update.
*/
@Test
- public void testUpdate() {
+ public void testUpdate() throws SQLException {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.UPDATE);
@@ -147,19 +148,18 @@ public void testUpdate() {
SQLUndoLog.setAfterImage(afterImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
-
- try {
- executor.executeOn(new MockConnection());
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ MockConnection connection = new MockConnection();
+ AbstractUndoExecutor spy = Mockito.spy(executor);
+ // skip data validation
+ Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
+ spy.executeOn(connection);
}
/**
* Test insert.
*/
@Test
- public void testInsert() {
+ public void testInsert() throws SQLException {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.INSERT);
@@ -217,19 +217,18 @@ public void testInsert() {
SQLUndoLog.setAfterImage(afterImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
-
- try {
- executor.executeOn(new MockConnection());
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ MockConnection connection = new MockConnection();
+ AbstractUndoExecutor spy = Mockito.spy(executor);
+ // skip data validation
+ Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
+ spy.executeOn(connection);
}
/**
* Test delete.
*/
@Test
- public void testDelete() {
+ public void testDelete() throws SQLException {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.DELETE);
@@ -287,12 +286,11 @@ public void testDelete() {
SQLUndoLog.setBeforeImage(beforeImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
-
- try {
- executor.executeOn(new MockConnection());
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ MockConnection connection = new MockConnection();
+ AbstractUndoExecutor spy = Mockito.spy(executor);
+ // skip data validation
+ Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
+ spy.executeOn(connection);
}
/**
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
index dcc8f5d4ddc..e8fe5504dc9 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
@@ -40,9 +40,10 @@ public class UndoLogManagerTest {
private static final int APPEND_IN_SIZE = 10;
- private static final int LIMIT_SIZE = 10;
- private static final String THE_APPEND_IN_SIZE_PARAM_String = " (?,?,?,?,?,?,?,?,?,?) ";
+ private static final String THE_APPEND_IN_SIZE_PARAM_STRING = " (?,?,?,?,?,?,?,?,?,?) ";
+
+ private static final String THE_DOUBLE_APPEND_IN_SIZE_PARAM_STRING = " (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
@Test
public void testBatchDeleteUndoLog() throws Exception {
@@ -57,7 +58,7 @@ public void testBatchDeleteUndoLog() throws Exception {
Connection connection = mock(Connection.class);
PreparedStatement preparedStatement = mock(PreparedStatement.class);
when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, LIMIT_SIZE, connection);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, connection);
//verify
for (int i = 1;i <= APPEND_IN_SIZE;i++){
@@ -72,11 +73,10 @@ public void testBatchDeleteUndoLog() throws Exception {
@Test
public void testToBatchDeleteUndoLogSql() {
String expectedSqlString="DELETE FROM undo_log WHERE branch_id IN " +
- THE_APPEND_IN_SIZE_PARAM_String +
+ THE_APPEND_IN_SIZE_PARAM_STRING +
" AND xid IN " +
- THE_APPEND_IN_SIZE_PARAM_String +
- " LIMIT " + LIMIT_SIZE;
- String batchDeleteUndoLogSql = UndoLogManager.toBatchDeleteUndoLogSql(APPEND_IN_SIZE, APPEND_IN_SIZE, LIMIT_SIZE);
+ THE_DOUBLE_APPEND_IN_SIZE_PARAM_STRING;
+ String batchDeleteUndoLogSql = UndoLogManager.toBatchDeleteUndoLogSql(APPEND_IN_SIZE * 2, APPEND_IN_SIZE);
System.out.println(batchDeleteUndoLogSql);
assertThat(batchDeleteUndoLogSql).isEqualTo(expectedSqlString);
}
@@ -85,7 +85,7 @@ public void testToBatchDeleteUndoLogSql() {
public void testAppendInParam() {
StringBuilder sqlBuilder = new StringBuilder();
UndoLogManager.appendInParam(APPEND_IN_SIZE, sqlBuilder);
- assertThat(sqlBuilder.toString()).isEqualTo(THE_APPEND_IN_SIZE_PARAM_String);
+ assertThat(sqlBuilder.toString()).isEqualTo(THE_APPEND_IN_SIZE_PARAM_STRING);
}
}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
index 879b77a88cd..a3fd52afb1a 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
@@ -26,7 +26,6 @@
import io.seata.rm.datasource.undo.KeywordChecker;
import io.seata.rm.datasource.undo.KeywordCheckerFactory;
import io.seata.rm.datasource.undo.SQLUndoLog;
-import io.seata.rm.datasource.undo.UndoExecutorTest;
import io.seata.rm.datasource.undo.mysql.MySQLUndoDeleteExecutor;
import io.seata.rm.datasource.undo.mysql.MySQLUndoInsertExecutor;
import io.seata.rm.datasource.undo.mysql.MySQLUndoUpdateExecutor;
diff --git a/server/pom.xml b/server/pom.xml
index 55290bec0ee..870f8187e7a 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -45,6 +45,24 @@
${project.version}
+
+
+ com.alibaba
+ druid
+
+
+ commons-dbcp
+ commons-dbcp
+
+
+ com.h2database
+ h2
+
+
+ mysql
+ mysql-connector-java
+
+
diff --git a/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java b/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
index d6655196eee..89fcbe94740 100644
--- a/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
+++ b/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
@@ -15,7 +15,6 @@
*/
package io.seata.server;
-import io.seata.common.XID;
import io.seata.core.exception.AbstractExceptionHandler;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.GlobalStatus;
@@ -106,8 +105,7 @@ public void execute(GlobalRollbackRequest request, GlobalRollbackResponse respon
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
TransactionException tex) {
super.onTransactionException(request, response, tex);
- GlobalSession globalSession = SessionHolder.findGlobalSession(
- XID.getTransactionId(request.getXid()));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid());
if (globalSession != null) {
response.setGlobalStatus(globalSession.getStatus());
} else {
@@ -118,8 +116,7 @@ public void onTransactionException(GlobalRollbackRequest request, GlobalRollback
@Override
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
super.onException(request, response, rex);
- GlobalSession globalSession = SessionHolder.findGlobalSession(
- XID.getTransactionId(request.getXid()));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid());
if (globalSession != null) {
response.setGlobalStatus(globalSession.getStatus());
} else {
diff --git a/server/src/main/java/io/seata/server/Server.java b/server/src/main/java/io/seata/server/Server.java
index 92273a3e68f..0cec9d18b87 100644
--- a/server/src/main/java/io/seata/server/Server.java
+++ b/server/src/main/java/io/seata/server/Server.java
@@ -42,7 +42,7 @@ public class Server {
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),
+ new LinkedBlockingQueue<>(MAX_TASK_QUEUE_SIZE),
new NamedThreadFactory("ServerHandlerThread", MAX_SERVER_POOL_SIZE), new ThreadPoolExecutor.CallerRunsPolicy());
/**
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 15063da2cb2..18c1e80395f 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
@@ -16,13 +16,17 @@
package io.seata.server.coordinator;
import java.io.IOException;
+import java.time.Duration;
import java.util.Collection;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import io.seata.common.XID;
import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.util.CollectionUtils;
+import io.seata.core.constants.ConfigurationKeys;
+import io.seata.common.util.DurationUtil;
+import io.seata.config.ConfigurationFactory;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.BranchStatus;
import io.seata.core.model.BranchType;
@@ -78,6 +82,44 @@ public class DefaultCoordinator extends AbstractTCInboundHandler
private static final int TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS = 5000;
+ /**
+ * The Committing retry delay.
+ */
+ protected int committingRetryDelay = CONFIG.getInt(ConfigurationKeys.COMMITING_RETRY_DELAY, 5);
+
+ /**
+ * The Asyn committing retry delay.
+ */
+ protected int asynCommittingRetryDelay = CONFIG.getInt(ConfigurationKeys.ASYN_COMMITING_RETRY_DELAY, 5);
+
+ /**
+ * The Rollbacking retry delay.
+ */
+ protected int rollbackingRetryDelay = CONFIG.getInt(ConfigurationKeys.ROLLBACKING_RETRY_DELAY, 5);
+
+ /**
+ * The Timeout retry delay.
+ */
+ protected int timeoutRetryDelay = CONFIG.getInt(ConfigurationKeys.TIMEOUT_RETRY_DELAY, 5);
+
+ private static final int ALWAYS_RETRY_BOUNDARY = 0;
+
+ private static final Duration MAX_COMMIT_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(ConfigurationKeys.SERVICE_PREFIX + "max.commit.retry.timeout", DurationUtil.DEFAULT_DURATION, 100);
+
+ private static final Duration MAX_ROLLBACK_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(ConfigurationKeys.SERVICE_PREFIX + "max.rollback.retry.timeout", DurationUtil.DEFAULT_DURATION, 100);
+
+ private ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("RetryRollbacking", 1));
+
+ private ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("RetryCommitting", 1));
+
+ private ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("AsyncCommitting", 1));
+
+ private ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("TxTimeoutCheck", 1));
+
private ServerMessageSender messageSender;
private Core core = CoreFactory.get();
@@ -156,7 +198,7 @@ public BranchStatus branchCommit(BranchType branchType, String xid, long branchI
request.setApplicationData(applicationData);
request.setBranchType(branchType);
- GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if(globalSession == null){
return BranchStatus.PhaseTwo_Committed;
}
@@ -165,9 +207,7 @@ public BranchStatus branchCommit(BranchType branchType, String xid, long branchI
BranchCommitResponse response = (BranchCommitResponse)messageSender.sendSyncRequest(resourceId,
branchSession.getClientId(), request);
return response.getBranchStatus();
- } catch (IOException e) {
- throw new TransactionException(FailedToSendBranchCommitRequest, branchId + "/" + xid, e);
- } catch (TimeoutException e) {
+ } catch (IOException | TimeoutException e) {
throw new TransactionException(FailedToSendBranchCommitRequest, branchId + "/" + xid, e);
}
}
@@ -185,7 +225,7 @@ public BranchStatus branchRollback(BranchType branchType, String xid, long branc
request.setApplicationData(applicationData);
request.setBranchType(branchType);
- GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if(globalSession == null){
return BranchStatus.PhaseTwo_Rollbacked;
}
@@ -194,27 +234,34 @@ public BranchStatus branchRollback(BranchType branchType, String xid, long branc
BranchRollbackResponse response = (BranchRollbackResponse)messageSender.sendSyncRequest(resourceId,
branchSession.getClientId(), request);
return response.getBranchStatus();
- } catch (IOException e) {
- throw new TransactionException(FailedToSendBranchRollbackRequest, branchId + "/" + xid, e);
- } catch (TimeoutException e) {
+ } catch (IOException | TimeoutException e) {
throw new TransactionException(FailedToSendBranchRollbackRequest, branchId + "/" + xid, e);
}
}
- private void timeoutCheck() throws TransactionException {
+ /**
+ * Timeout check.
+ *
+ * @throws TransactionException the transaction exception
+ */
+ protected void timeoutCheck() throws TransactionException {
Collection allSessions = SessionHolder.getRootSessionManager().allSessions();
+ if(CollectionUtils.isEmpty(allSessions)){
+ return;
+ }
if (allSessions.size() > 0 && LOGGER.isDebugEnabled()) {
LOGGER.debug("Transaction Timeout Check Begin: " + allSessions.size());
}
for (GlobalSession globalSession : allSessions) {
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug(globalSession.getTransactionId() + " " + globalSession.getStatus() + " " +
+ LOGGER.debug(globalSession.getXid() + " " + globalSession.getStatus() + " " +
globalSession.getBeginTime() + " " + globalSession.getTimeout());
}
boolean shouldTimeout = globalSession.lockAndExcute(() -> {
if (globalSession.getStatus() != GlobalStatus.Begin || !globalSession.isTimeout()) {
return false;
}
+ globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
globalSession.close();
globalSession.changeStatus(GlobalStatus.TimeoutRollbacking);
return true;
@@ -223,7 +270,7 @@ private void timeoutCheck() throws TransactionException {
continue;
}
LOGGER.info(
- "Global transaction[" + globalSession.getTransactionId() + "] is timeout and will be rolled back.");
+ "Global transaction[" + globalSession.getXid() + "] is timeout and will be rolled back.");
globalSession.addSessionLifecycleListener(SessionHolder.getRetryRollbackingSessionManager());
SessionHolder.getRetryRollbackingSessionManager().addGlobalSession(globalSession);
@@ -235,107 +282,129 @@ private void timeoutCheck() throws TransactionException {
}
- private void handleRetryRollbacking() {
+ /**
+ * Handle retry rollbacking.
+ */
+ protected void handleRetryRollbacking() {
Collection rollbackingSessions = SessionHolder.getRetryRollbackingSessionManager().allSessions();
+ if(CollectionUtils.isEmpty(rollbackingSessions)){
+ return;
+ }
+ long now = System.currentTimeMillis();
for (GlobalSession rollbackingSession : rollbackingSessions) {
try {
+ if(isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT.toMillis(), rollbackingSession.getBeginTime())){
+ /**
+ * Prevent thread safety issues
+ */
+ SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(rollbackingSession);
+ LOGGER.error("GlobalSession rollback retry timeout [{}]", rollbackingSession.getTransactionId());
+ continue;
+ }
+ rollbackingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalRollback(rollbackingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry rollbacking [{}] {} {}",
- rollbackingSession.getTransactionId(), ex.getCode(), ex.getMessage());
+ rollbackingSession.getXid(), ex.getCode(), ex.getMessage());
}
}
}
- private void handleRetryCommitting() {
+ /**
+ * Handle retry committing.
+ */
+ protected void handleRetryCommitting() {
Collection committingSessions = SessionHolder.getRetryCommittingSessionManager().allSessions();
+ if(CollectionUtils.isEmpty(committingSessions)){
+ return;
+ }
+ long now = System.currentTimeMillis();
for (GlobalSession committingSession : committingSessions) {
try {
+ if(isRetryTimeout(now, MAX_COMMIT_RETRY_TIMEOUT.toMillis(), committingSession.getBeginTime())){
+ /**
+ * Prevent thread safety issues
+ */
+ SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(committingSession);
+ LOGGER.error("GlobalSession commit retry timeout [{}]", committingSession.getTransactionId());
+ continue;
+ }
+ committingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalCommit(committingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry committing [{}] {} {}",
- committingSession.getTransactionId(), ex.getCode(), ex.getMessage());
+ committingSession.getXid(), ex.getCode(), ex.getMessage());
}
}
}
- private void handleAsyncCommitting() {
+ private boolean isRetryTimeout(long now, long timeout, long beginTime){
+ /**
+ * Start timing when the session begin
+ */
+ if(timeout >= ALWAYS_RETRY_BOUNDARY &&
+ now - beginTime > timeout){
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Handle async committing.
+ */
+ protected void handleAsyncCommitting() {
Collection asyncCommittingSessions = SessionHolder.getAsyncCommittingSessionManager()
.allSessions();
+ if(CollectionUtils.isEmpty(asyncCommittingSessions)){
+ return;
+ }
for (GlobalSession asyncCommittingSession : asyncCommittingSessions) {
try {
+ asyncCommittingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalCommit(asyncCommittingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to async committing [{}] {} {}",
- asyncCommittingSession.getTransactionId(), ex.getCode(), ex.getMessage());
+ asyncCommittingSession.getXid(), ex.getCode(), ex.getMessage());
}
}
}
- private ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("RetryRollbacking", 1));
-
- private ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("RetryCommitting", 1));
-
- private ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("AsyncCommitting", 1));
-
- private ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("TxTimeoutCheck", 1));
/**
* Init.
*/
public void init() {
- retryRollbacking.scheduleAtFixedRate(new Runnable() {
-
- @Override
- public void run() {
- try {
- handleRetryRollbacking();
- } catch (Exception e) {
- LOGGER.info("Exception retry rollbacking ... ", e);
- }
-
+ retryRollbacking.scheduleAtFixedRate(() -> {
+ try {
+ handleRetryRollbacking();
+ } catch (Exception e) {
+ LOGGER.info("Exception retry rollbacking ... ", e);
}
- }, 0, 5, TimeUnit.MILLISECONDS);
-
- retryCommitting.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- try {
- handleRetryCommitting();
- } catch (Exception e) {
- LOGGER.info("Exception retry committing ... ", e);
- }
+ }, 0, rollbackingRetryDelay, TimeUnit.SECONDS);
+ retryCommitting.scheduleAtFixedRate(() -> {
+ try {
+ handleRetryCommitting();
+ } catch (Exception e) {
+ LOGGER.info("Exception retry committing ... ", e);
}
- }, 0, 5, TimeUnit.MILLISECONDS);
-
- asyncCommitting.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- try {
- handleAsyncCommitting();
- } catch (Exception e) {
- LOGGER.info("Exception async committing ... ", e);
- }
+ }, 0, committingRetryDelay, TimeUnit.SECONDS);
+ asyncCommitting.scheduleAtFixedRate(() -> {
+ try {
+ handleAsyncCommitting();
+ } catch (Exception e) {
+ LOGGER.info("Exception async committing ... ", e);
}
- }, 0, 10, TimeUnit.MILLISECONDS);
-
- timeoutCheck.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- try {
- timeoutCheck();
- } catch (Exception e) {
- LOGGER.info("Exception timeout checking ... ", e);
- }
+ }, 0, asynCommittingRetryDelay, TimeUnit.SECONDS);
+ timeoutCheck.scheduleAtFixedRate(() -> {
+ try {
+ timeoutCheck();
+ } catch (Exception e) {
+ LOGGER.info("Exception timeout checking ... ", e);
}
- }, 0, 2, TimeUnit.MILLISECONDS);
+ }, 0, timeoutRetryDelay, TimeUnit.SECONDS);
}
@Override
@@ -369,14 +438,14 @@ public void destroy() {
retryCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
asyncCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
timeoutCheck.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
- } catch (InterruptedException ingore) {
+ } catch (InterruptedException ignore) {
}
- // 2. sencond close netty flow
+ // 2. second close netty flow
if (messageSender instanceof RpcServer){
((RpcServer) messageSender).destroy();
}
- // 3. last destory SessionHolder
+ // 3. last destroy SessionHolder
SessionHolder.destory();
}
}
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 1ba36763f1f..cd10d4281ba 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
@@ -23,7 +23,7 @@
import io.seata.core.model.GlobalStatus;
import io.seata.core.model.ResourceManagerInbound;
import io.seata.server.lock.LockManager;
-import io.seata.server.lock.LockManagerFactory;
+import io.seata.server.lock.LockerFactory;
import io.seata.server.session.BranchSession;
import io.seata.server.session.GlobalSession;
import io.seata.server.session.SessionHelper;
@@ -46,7 +46,7 @@ public class DefaultCore implements Core {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCore.class);
- private LockManager lockManager = LockManagerFactory.get();
+ private LockManager lockManager = LockerFactory.getLockManager();
private ResourceManagerInbound resourceManagerInbound;
@@ -58,7 +58,7 @@ public void setResourceManagerInbound(ResourceManagerInbound resourceManagerInbo
@Override
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
String applicationData, String lockKeys) throws TransactionException {
- GlobalSession globalSession = assertGlobalSessionNotNull(XID.getTransactionId(xid));
+ GlobalSession globalSession = assertGlobalSessionNotNull(xid);
return globalSession.lockAndExcute(() -> {
if (!globalSession.isActive()) {
throw new TransactionException(GlobalTransactionNotActive, "Current Status: " + globalSession.getStatus());
@@ -67,6 +67,7 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
throw new TransactionException(GlobalTransactionStatusInvalid,
globalSession.getStatus() + " while expecting " + GlobalStatus.Begin);
}
+ globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
applicationData, lockKeys, clientId);
if (!branchSession.lock()) {
@@ -81,10 +82,10 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
});
}
- private GlobalSession assertGlobalSessionNotNull(long transactionId) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(transactionId);
+ private GlobalSession assertGlobalSessionNotNull(String xid) throws TransactionException {
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if (globalSession == null) {
- throw new TransactionException(TransactionExceptionCode.GlobalTransactionNotExist, "" + transactionId + "");
+ throw new TransactionException(TransactionExceptionCode.GlobalTransactionNotExist, "" + xid + "");
}
return globalSession;
}
@@ -93,11 +94,12 @@ private GlobalSession assertGlobalSessionNotNull(long transactionId) throws Tran
@Override
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
String applicationData) throws TransactionException {
- GlobalSession globalSession = assertGlobalSessionNotNull(XID.getTransactionId(xid));
+ GlobalSession globalSession = assertGlobalSessionNotNull(xid);
BranchSession branchSession = globalSession.getBranch(branchId);
if (branchSession == null) {
throw new TransactionException(BranchTransactionNotExist);
}
+ globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
globalSession.changeBranchStatus(branchSession, status);
}
@@ -105,7 +107,7 @@ public void branchReport(BranchType branchType, String xid, long branchId, Branc
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
throws TransactionException {
if (branchType == BranchType.AT) {
- return lockManager.isLockable(XID.getTransactionId(xid), resourceId, lockKeys);
+ return lockManager.isLockable(xid, resourceId, lockKeys);
} else {
return true;
}
@@ -121,17 +123,19 @@ public String begin(String applicationId, String transactionServiceGroup, String
session.begin();
- return XID.generateXID(session.getTransactionId());
+ return session.getXid();
}
@Override
public GlobalStatus commit(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if (globalSession == null) {
return GlobalStatus.Finished;
}
+ globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
// just lock changeStatus
boolean shouldCommit = globalSession.lockAndExcute(() -> {
+ //the lock should release after branch commit
globalSession.closeAndClean(); // Highlight: Firstly, close the session, then no more branch can be registered.
if (globalSession.getStatus() == GlobalStatus.Begin) {
globalSession.changeStatus(GlobalStatus.Committing);
@@ -175,7 +179,7 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
} else {
SessionHelper.endCommitFailed(globalSession);
LOGGER.error("Finally, failed to commit global[{}] since branch[{}] commit failed",
- globalSession.getTransactionId(), branchSession.getBranchId());
+ globalSession.getXid(), branchSession.getBranchId());
return;
}
default:
@@ -189,7 +193,7 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
} else {
LOGGER.error(
"Failed to commit global[{}] since branch[{}] commit failed, will retry later.",
- globalSession.getTransactionId(), branchSession.getBranchId());
+ globalSession.getXid(), branchSession.getBranchId());
return;
}
@@ -206,11 +210,11 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
}
if (globalSession.hasBranch()) {
- LOGGER.info("Global[{}] committing is NOT done.", globalSession.getTransactionId());
+ LOGGER.info("Global[{}] committing is NOT done.", globalSession.getXid());
return;
}
SessionHelper.endCommitted(globalSession);
- LOGGER.info("Global[{}] committing is successfully done.", globalSession.getTransactionId());
+ LOGGER.info("Global[{}] committing is successfully done.", globalSession.getXid());
}
private void asyncCommit(GlobalSession globalSession) throws TransactionException {
@@ -238,10 +242,11 @@ private void queueToRetryRollback(GlobalSession globalSession) throws Transactio
@Override
public GlobalStatus rollback(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
if (globalSession == null) {
return GlobalStatus.Finished;
}
+ globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
// just lock changeStatus
boolean shouldRollBack = globalSession.lockAndExcute(() -> {
globalSession.close(); // Highlight: Firstly, close the session, then no more branch can be registered.
@@ -279,7 +284,7 @@ public void doGlobalRollback(GlobalSession globalSession, boolean retrying) thro
continue;
case PhaseTwo_RollbackFailed_Unretryable:
SessionHelper.endRollbackFailed(globalSession);
- LOGGER.error("Failed to rollback global[" + globalSession.getTransactionId() + "] since branch["
+ LOGGER.error("Failed to rollback global[" + globalSession.getXid() + "] since branch["
+ branchSession.getBranchId() + "] rollback failed");
return;
default:
@@ -304,7 +309,7 @@ public void doGlobalRollback(GlobalSession globalSession, boolean retrying) thro
@Override
public GlobalStatus getStatus(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
+ GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
return globalSession.getStatus();
}
}
diff --git a/server/src/main/java/io/seata/server/lock/AbstractLockManager.java b/server/src/main/java/io/seata/server/lock/AbstractLockManager.java
new file mode 100644
index 00000000000..a8db3a54d92
--- /dev/null
+++ b/server/src/main/java/io/seata/server/lock/AbstractLockManager.java
@@ -0,0 +1,117 @@
+/*
+ * 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.lock;
+
+import io.seata.common.XID;
+import io.seata.common.util.StringUtils;
+import io.seata.core.lock.RowLock;
+import io.seata.server.session.BranchSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The type Abstract lock manager.
+ *
+ * @author zhangsen
+ * @data 2019 /4/25
+ */
+public abstract class AbstractLockManager implements LockManager {
+
+ /**
+ * The constant LOGGER.
+ */
+ protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockManager.class);
+
+ /**
+ * Collect row locks list.`
+ *
+ * @param branchSession the branch session
+ * @return the list
+ */
+ protected List collectRowLocks(BranchSession branchSession){
+ List locks = new ArrayList<>();
+ if(branchSession == null || StringUtils.isBlank(branchSession.getLockKey())){
+ return locks;
+ }
+ String xid = branchSession.getXid();
+ String resourceId = branchSession.getResourceId();
+ long transactionId = branchSession.getTransactionId();
+
+ String lockKey = branchSession.getLockKey();
+
+ return collectRowLocks(lockKey, resourceId, xid, transactionId, branchSession.getBranchId());
+ }
+
+ /**
+ * Collect row locks list.
+ *
+ * @param lockKey the lock key
+ * @param resourceId the resource id
+ * @param xid the xid
+ * @return the list
+ */
+ protected List collectRowLocks(String lockKey, String resourceId, String xid) {
+ return collectRowLocks(lockKey, resourceId, xid, XID.getTransactionId(xid), null);
+ }
+
+ /**
+ * Collect row locks list.
+ *
+ * @param lockKey the lock key
+ * @param resourceId the resource id
+ * @param xid the xid
+ * @param transactionId the transaction id
+ * @param branchID the branch id
+ * @return the list
+ */
+ protected List collectRowLocks(String lockKey, String resourceId, String xid, Long transactionId, Long branchID){
+ List locks = new ArrayList();
+
+ String[] tableGroupedLockKeys = lockKey.split(";");
+ for (String tableGroupedLockKey : tableGroupedLockKeys) {
+ int idx = tableGroupedLockKey.indexOf(":");
+ if (idx < 0) {
+ return locks;
+ }
+ String tableName = tableGroupedLockKey.substring(0, idx);
+ String mergedPKs = tableGroupedLockKey.substring(idx + 1);
+ if(StringUtils.isBlank(mergedPKs)){
+ return locks;
+ }
+ String[] pks = mergedPKs.split(",");
+ if(pks == null || pks.length == 0){
+ return locks;
+ }
+ for(String pk : pks){
+ if(StringUtils.isNotBlank(pk)){
+ RowLock rowLock = new RowLock();
+ rowLock.setXid(xid);
+ rowLock.setTransactionId(transactionId);
+ rowLock.setBranchId(branchID);
+ rowLock.setTableName(tableName);
+ rowLock.setPk(pk);
+ rowLock.setResourceId(resourceId);
+ locks.add(rowLock);
+ }
+ }
+ }
+ return locks;
+ }
+
+}
diff --git a/server/src/main/java/io/seata/server/lock/DefaultLockManager.java b/server/src/main/java/io/seata/server/lock/DefaultLockManager.java
new file mode 100644
index 00000000000..dd66e979987
--- /dev/null
+++ b/server/src/main/java/io/seata/server/lock/DefaultLockManager.java
@@ -0,0 +1,103 @@
+/*
+ * 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.lock;
+
+import io.seata.common.util.CollectionUtils;
+import io.seata.common.util.StringUtils;
+import io.seata.core.exception.TransactionException;
+import io.seata.core.lock.Locker;
+import io.seata.core.lock.RowLock;
+import io.seata.server.session.BranchSession;
+
+import java.util.List;
+
+/**
+ * The type Default lock manager.
+ *
+ * @author zhangsen
+ * @data 2019 -05-15
+ */
+public class DefaultLockManager extends AbstractLockManager {
+
+ private static Locker locker = null;
+
+ @Override
+ public boolean acquireLock(BranchSession branchSession) throws TransactionException {
+ String lockKey = branchSession.getLockKey();
+ if (StringUtils.isNullOrEmpty(lockKey)) {
+ //no lock
+ return true;
+ }
+ //get locks of branch
+ List locks = collectRowLocks(branchSession);
+ if(CollectionUtils.isEmpty(locks)){
+ //no lock
+ return true;
+ }
+ return getLocker(branchSession).acquireLock(locks);
+ }
+
+ @Override
+ public boolean releaseLock(BranchSession branchSession) throws TransactionException {
+ List locks = collectRowLocks(branchSession);
+ if(CollectionUtils.isEmpty(locks)){
+ //no lock
+ return true;
+ }
+ try{
+ return getLocker(branchSession).releaseLock(locks);
+ }catch(Exception t){
+ LOGGER.error("unLock error, branchSession:" + branchSession, t);
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException {
+ List locks = collectRowLocks(lockKey, resourceId, xid);
+ try{
+ return getLocker().isLockable(locks);
+ }catch(Exception t){
+ LOGGER.error("isLockable error, xid:" + xid + ", resourceId:"+resourceId + ", lockKey:"+lockKey, t);
+ return false;
+ }
+ }
+
+ @Override
+ public void cleanAllLocks() throws TransactionException {
+ getLocker().cleanAllLocks();
+ }
+
+ /**
+ * Gets locker.
+ *
+ * @return the locker
+ */
+ protected Locker getLocker() {
+ return getLocker(null);
+ }
+
+ /**
+ * Gets locker.
+ *
+ * @param branchSession the branch session
+ * @return the locker
+ */
+ protected Locker getLocker(BranchSession branchSession) {
+ return LockerFactory.get(branchSession);
+ }
+
+}
diff --git a/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java b/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java
deleted file mode 100644
index 14a68549987..00000000000
--- a/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java
+++ /dev/null
@@ -1,186 +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.server.lock;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import io.netty.util.internal.ConcurrentSet;
-import io.seata.common.exception.ShouldNeverHappenException;
-import io.seata.common.util.StringUtils;
-import io.seata.core.exception.TransactionException;
-import io.seata.server.session.BranchSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The type Default lock manager.
- *
- * @author sharajava
- */
-public class DefaultLockManagerImpl implements LockManager {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLockManagerImpl.class);
-
- private static final int BUCKET_PER_TABLE = 128;
-
- private static final
- ConcurrentHashMap>>>
- LOCK_MAP = new ConcurrentHashMap>>>();
-
- @Override
- public boolean acquireLock(BranchSession branchSession) throws TransactionException {
- String resourceId = branchSession.getResourceId();
- long transactionId = branchSession.getTransactionId();
- ConcurrentHashMap>> dbLockMap = LOCK_MAP.get(resourceId);
- if (dbLockMap == null) {
- LOCK_MAP.putIfAbsent(resourceId,
- new ConcurrentHashMap>>());
- dbLockMap = LOCK_MAP.get(resourceId);
- }
- ConcurrentHashMap
diff --git a/common/src/main/java/io/seata/common/Constants.java b/common/src/main/java/io/seata/common/Constants.java
index e39d856f5b9..a76bacb155d 100644
--- a/common/src/main/java/io/seata/common/Constants.java
+++ b/common/src/main/java/io/seata/common/Constants.java
@@ -15,8 +15,6 @@
*/
package io.seata.common;
-import java.nio.charset.Charset;
-
/**
* The type Constants.
*
@@ -99,13 +97,4 @@ public class Constants {
*/
public final static String TCC_ACTION_CONTEXT = "actionContext";
- /**
- * default charset name
- */
- public static final String DEFAULT_CHARSET_NAME = "UTF-8";
-
- /**
- * default charset is utf-8
- */
- public static final Charset DEFAULT_CHARSET = Charset.forName(DEFAULT_CHARSET_NAME);
}
diff --git a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
index 4c80b9c59f3..d10d95999bc 100644
--- a/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
+++ b/common/src/main/java/io/seata/common/loader/EnhancedServiceLoader.java
@@ -18,8 +18,6 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
@@ -29,7 +27,6 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import io.seata.common.Constants;
import io.seata.common.executor.Initialize;
import io.seata.common.util.CollectionUtils;
@@ -105,48 +102,12 @@ public static S load(Class service, String activateName, ClassLoader load
return loadFile(service, activateName, loader);
}
- /**
- * Load s.
- *
- * @param the type parameter
- * @param service the service
- * @param activateName the activate name
- * @param args the args
- * @return the s
- * @throws EnhancedServiceNotFoundException the enhanced service not found exception
- */
- public static S load(Class service, String activateName, Object[] args) throws EnhancedServiceNotFoundException {
- Class[] argsType = null;
- if(args != null && args.length > 0){
- argsType = new Class[args.length];
- for(int i = 0; i < args.length; i ++){
- argsType[i] = args[i].getClass();
- }
- }
- return loadFile(service, activateName, findClassLoader(), argsType, args);
- }
-
- /**
- * Load s.
- *
- * @param the type parameter
- * @param service the service
- * @param activateName the activate name
- * @param argsType the args type
- * @param args the args
- * @return the s
- * @throws EnhancedServiceNotFoundException the enhanced service not found exception
- */
- public static S load(Class service, String activateName, Class[] argsType, Object[] args) throws EnhancedServiceNotFoundException {
- return loadFile(service, activateName, findClassLoader(), argsType, args);
- }
-
/**
* get all implements
*
* @param the type parameter
* @param service the service
- * @return list list
+ * @return list
*/
public static List loadAll(Class service) {
List allInstances = new ArrayList<>();
@@ -156,7 +117,7 @@ public static List loadAll(Class service) {
}
try {
for (Class clazz : allClazzs) {
- allInstances.add(initInstance(service, clazz, null, null));
+ allInstances.add(initInstance(service, clazz));
}
} catch (Throwable t) {
throw new EnhancedServiceNotFoundException(t);
@@ -189,12 +150,8 @@ public static List getAllExtensionClass(Class service, ClassLoader
return findAllExtensionClass(service, null, loader);
}
+ @SuppressWarnings("rawtypes")
private static S loadFile(Class service, String activateName, ClassLoader loader) {
- return loadFile(service, activateName, loader, null, null);
- }
-
- @SuppressWarnings("rawtypes")
- private static S loadFile(Class service, String activateName, ClassLoader loader, Class[] argTypes, Object[] args) {
try {
boolean foundFromCache = true;
List extensions = providers.get(service);
@@ -216,7 +173,7 @@ private static S loadFile(Class service, String activateName, ClassLoader
Class clz = extensions.get(i);
@SuppressWarnings("unchecked")
LoadLevel activate = (LoadLevel)clz.getAnnotation(LoadLevel.class);
- if (activate != null && activateName.equalsIgnoreCase(activate.name())) {
+ if (activate != null && activateName.equals(activate.name())) {
activateExtensions.add(clz);
}
}
@@ -230,7 +187,7 @@ private static S loadFile(Class service, String activateName, ClassLoader
+ "] and classloader : " + ObjectUtils.toString(loader));
}
Class> extension = extensions.get(extensions.size() - 1);
- S result = initInstance(service, extension, argTypes, args);
+ S result = initInstance(service, extension);
if (!foundFromCache && LOGGER.isInfoEnabled()) {
LOGGER.info("load " + service.getSimpleName() + "[" + activateName + "] extension by class[" + extension
.getName() + "]");
@@ -302,7 +259,7 @@ private static void loadFile(Class> service, String dir, ClassLoader classLoad
java.net.URL url = urls.nextElement();
BufferedReader reader = null;
try {
- reader = new BufferedReader(new InputStreamReader(url.openStream(), Constants.DEFAULT_CHARSET));
+ reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
String line = null;
while ((line = reader.readLine()) != null) {
final int ci = line.indexOf('#');
@@ -335,26 +292,13 @@ private static void loadFile(Class> service, String dir, ClassLoader classLoad
* @param the type parameter
* @param service the service
* @param implClazz the impl clazz
- * @param argTypes the arg types
- * @param args the args
- * @return s s
- * @throws IllegalAccessException the illegal access exception
- * @throws InstantiationException the instantiation exception
- * @throws NoSuchMethodException the no such method exception
- * @throws InvocationTargetException the invocation target exception
+ * @return s
+ * @throws IllegalAccessException the illegal access exception
+ * @throws InstantiationException the instantiation exception
*/
- protected static S initInstance(Class service, Class implClazz, Class[] argTypes, Object[] args)
- throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
- S s = null;
- if(argTypes != null && args != null){
- // Constructor with arguments
- Constructor constructor = implClazz.getDeclaredConstructor(argTypes);
- constructor.setAccessible(true);
- s = service.cast(constructor.newInstance(args));
- }else {
- // default Constructor
- s = service.cast(implClazz.newInstance());
- }
+ protected static S initInstance(Class service, Class implClazz)
+ throws IllegalAccessException, InstantiationException {
+ S s = service.cast(implClazz.newInstance());
if (s instanceof Initialize) {
((Initialize)s).init();
}
diff --git a/common/src/main/java/io/seata/common/loader/LoadLevel.java b/common/src/main/java/io/seata/common/loader/LoadLevel.java
index b887ed509b0..b01ebf76c74 100644
--- a/common/src/main/java/io/seata/common/loader/LoadLevel.java
+++ b/common/src/main/java/io/seata/common/loader/LoadLevel.java
@@ -43,5 +43,5 @@
*
* @return the int
*/
- int order() default 0;
+ int order();
}
diff --git a/common/src/main/java/io/seata/common/util/BlobUtils.java b/common/src/main/java/io/seata/common/util/BlobUtils.java
index 60ddc7eaabc..3eb62aa0c28 100644
--- a/common/src/main/java/io/seata/common/util/BlobUtils.java
+++ b/common/src/main/java/io/seata/common/util/BlobUtils.java
@@ -15,18 +15,19 @@
*/
package io.seata.common.util;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
import java.sql.Blob;
import javax.sql.rowset.serial.SerialBlob;
-import io.seata.common.Constants;
+import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.common.exception.ShouldNeverHappenException;
/**
* The type Blob utils.
*
* @author jimin.jm @alibaba-inc.com
- * @author Geng Zhang
*/
public class BlobUtils {
@@ -46,7 +47,7 @@ public static Blob string2blob(String str) {
}
try {
- return new SerialBlob(str.getBytes(Constants.DEFAULT_CHARSET));
+ return new SerialBlob(str.getBytes());
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
@@ -64,43 +65,26 @@ public static String blob2string(Blob blob) {
}
try {
- return new String(blob.getBytes((long) 1, (int) blob.length()), Constants.DEFAULT_CHARSET);
- } catch (Exception e) {
- throw new ShouldNeverHappenException(e);
- }
- }
-
- /**
- * Byte array to blob
- *
- * @param bytes the byte array
- * @return the blob
- */
- public static Blob bytes2Blob(byte[] bytes) {
- if (bytes == null) {
- return null;
- }
-
- try {
- return new SerialBlob(bytes);
+ return new String(blob.getBytes((long)1, (int)blob.length()));
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
}
/**
- * Blob to byte array.
+ * Input stream 2 string string.
*
- * @param blob the blob
- * @return the byte array
+ * @param is the is
+ * @return the string
*/
- public static byte[] blob2Bytes(Blob blob) {
- if (blob == null) {
- return null;
- }
-
+ public static String inputStream2String(InputStream is) {
try {
- return blob.getBytes((long) 1, (int) blob.length());
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int i = -1;
+ while ((i = is.read()) != -1) {
+ baos.write(i);
+ }
+ return baos.toString();
} catch (Exception e) {
throw new ShouldNeverHappenException(e);
}
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 d56b80eb1ec..76126fc4cf4 100644
--- a/common/src/main/java/io/seata/common/util/CollectionUtils.java
+++ b/common/src/main/java/io/seata/common/util/CollectionUtils.java
@@ -16,7 +16,6 @@
package io.seata.common.util;
import java.util.Collection;
-import java.util.Iterator;
/**
* The type Collection utils.
@@ -46,49 +45,6 @@ public static boolean isNotEmpty(Collection col){
return col != null && col.size() > 0;
}
- /**
- * Is empty boolean.
- *
- * @param array the array
- * @return the boolean
- */
- public static boolean isEmpty(Object[] array){
- return !isNotEmpty(array);
- }
-
- /**
- * Is not empty boolean.
- *
- * @param array the array
- * @return the boolean
- */
- public static boolean isNotEmpty(Object[] array){
- return array != null && array.length > 0;
- }
-
- /**
- * To string string.
- *
- * @param col the col
- * @return the string
- */
- public static String toString(Collection col){
- if(isEmpty(col)){
- return "";
- }
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- Iterator it = col.iterator();
- while (it.hasNext()){
- Object obj = it.next();
- sb.append(StringUtils.toString(obj));
- sb.append(",");
- }
- sb.deleteCharAt(sb.length() - 1);
- sb.append("]");
- return sb.toString();
- }
-
/**
* Is size equals boolean.
*
diff --git a/common/src/main/java/io/seata/common/util/DurationUtil.java b/common/src/main/java/io/seata/common/util/DurationUtil.java
deleted file mode 100644
index 567fc85e3f5..00000000000
--- a/common/src/main/java/io/seata/common/util/DurationUtil.java
+++ /dev/null
@@ -1,74 +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.common.util;
-
-import java.time.Duration;
-
-/**
- * @author XCXCXCXCX
- */
-public class DurationUtil {
-
- public static final Duration DEFAULT_DURATION = Duration.ofMillis(-1);
-
- public static final String DAY_UNIT = "d";
- public static final String HOUR_UNIT = "h";
- public static final String MINIUTE_UNIT = "m";
- public static final String SECOND_UNIT = "s";
- public static final String MILLIS_SECOND_UNIT = "ms";
-
- public static Duration parse(String str) {
- if(StringUtils.isBlank(str)){
- return DEFAULT_DURATION;
- }
-
- if (str.contains(MILLIS_SECOND_UNIT)) {
- Long value = doParse(MILLIS_SECOND_UNIT, str);
- return value == null ? null : Duration.ofMillis(value);
- } else if (str.contains(DAY_UNIT)) {
- Long value = doParse(DAY_UNIT, str);
- return value == null ? null : Duration.ofDays(value);
- } else if (str.contains(HOUR_UNIT)) {
- Long value = doParse(HOUR_UNIT, str);
- return value == null ? null : Duration.ofHours(value);
- } else if (str.contains(MINIUTE_UNIT)) {
- Long value = doParse(MINIUTE_UNIT, str);
- return value == null ? null : Duration.ofMinutes(value);
- } else if (str.contains(SECOND_UNIT)) {
- Long value = doParse(SECOND_UNIT, str);
- return value == null ? null : Duration.ofSeconds(value);
- }
- try {
- int millis = Integer.parseInt(str);
- return Duration.ofMillis(millis);
- }catch (Exception e){
- throw new UnsupportedOperationException(str + " can't parse to duration", e);
- }
- }
-
- private static Long doParse(String unit, String str) {
- str = str.replace(unit, "");
- if ("".equals(str)) {
- return null;
- }
- try {
- return Long.parseLong(str);
- } catch (NumberFormatException e) {
- throw new UnsupportedOperationException("\"" + str + "\" can't parse to Duration", e);
- }
- }
-
-}
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 e6a1714e78b..217538aae17 100644
--- a/common/src/main/java/io/seata/common/util/StringUtils.java
+++ b/common/src/main/java/io/seata/common/util/StringUtils.java
@@ -15,17 +15,19 @@
*/
package io.seata.common.util;
-import io.seata.common.Constants;
-import io.seata.common.exception.ShouldNeverHappenException;
-
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
+import java.sql.Blob;
+import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
+import javax.sql.rowset.serial.SerialBlob;
+
/**
* The type String utils.
*
@@ -35,6 +37,7 @@
public class StringUtils {
private StringUtils() {
+
}
/**
@@ -51,7 +54,7 @@ public static boolean isNullOrEmpty(String str) {
* Is blank string ?
*
* @param str the str
- * @return boolean boolean
+ * @return boolean
*/
public static boolean isBlank(String str) {
int length;
@@ -71,7 +74,7 @@ public static boolean isBlank(String str) {
* Is Not blank string ?
*
* @param str the str
- * @return boolean boolean
+ * @return boolean
*/
public static boolean isNotBlank(String str) {
int length;
@@ -88,83 +91,56 @@ public static boolean isNotBlank(String str) {
return false;
}
- /**
- * Equals boolean.
- *
- * @param a the a
- * @param b the b
- * @return boolean
- */
- public static boolean equals(String a, String b) {
- if (a == null) {
- return b == null;
- }
- return a.equals(b);
- }
-
/**
- * Equals ignore case boolean.
+ * String 2 blob blob.
*
- * @param a the a
- * @param b the b
- * @return the boolean
+ * @param str the str
+ * @return the blob
+ * @throws SQLException the sql exception
*/
- public static boolean equalsIgnoreCase(String a, String b) {
- if (a == null) {
- return b == null;
+ public static Blob string2blob(String str) throws SQLException {
+ if (str == null) {
+ return null;
}
- return a.equalsIgnoreCase(b);
+ return new SerialBlob(str.getBytes());
}
/**
- * Input stream 2 string string.
+ * Blob 2 string string.
*
- * @param is the is
+ * @param blob the blob
* @return the string
+ * @throws SQLException the sql exception
*/
- public static String inputStream2String(InputStream is) {
- if (is == null) {
+ public static String blob2string(Blob blob) throws SQLException {
+ if (blob == null) {
return null;
}
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int i = -1;
- while ((i = is.read()) != -1) {
- baos.write(i);
- }
- return baos.toString(Constants.DEFAULT_CHARSET_NAME);
- } catch (Exception e) {
- throw new ShouldNeverHappenException(e);
- }
+
+ return new String(blob.getBytes((long)1, (int)blob.length()));
}
/**
- * Input stream to byte array
+ * Input stream 2 string string.
*
* @param is the is
- * @return the byte array
+ * @return the string
+ * @throws IOException the io exception
*/
- public static byte[] inputStream2Bytes(InputStream is) {
- if (is == null) {
- return null;
- }
- try {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- int i = -1;
- while ((i = is.read()) != -1) {
- baos.write(i);
- }
- return baos.toByteArray();
- } catch (Exception e) {
- throw new ShouldNeverHappenException(e);
+ public static String inputStream2String(InputStream is) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int i = -1;
+ while ((i = is.read()) != -1) {
+ baos.write(i);
}
+ return baos.toString();
}
/**
* Object.toString()
*
* @param obj the obj
- * @return string string
+ * @return string
*/
public static String toString(Object obj){
if (obj == null){
@@ -221,4 +197,32 @@ public static String toString(Object obj){
}
return sb.toString();
}
+
+ /**
+ * Equals boolean.
+ *
+ * @param a the a
+ * @param b the b
+ * @return boolean
+ */
+ public static boolean equals(String a, String b) {
+ if (a == null) {
+ return b == null;
+ }
+ return a.equals(b);
+ }
+
+ /**
+ * Equals ignore case boolean.
+ *
+ * @param a the a
+ * @param b the b
+ * @return the boolean
+ */
+ public static boolean equalsIgnoreCase(String a, String b) {
+ if (a == null) {
+ return b == null;
+ }
+ return a.equalsIgnoreCase(b);
+ }
}
diff --git a/common/src/test/java/io/seata/common/util/BlobUtilsTest.java b/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
index f643ad49caa..53a0a6217ae 100644
--- a/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
+++ b/common/src/test/java/io/seata/common/util/BlobUtilsTest.java
@@ -15,22 +15,21 @@
*/
package io.seata.common.util;
-import java.io.UnsupportedEncodingException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialBlob;
-import io.seata.common.Constants;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type Blob utils test.
*
* @author Otis.z
- * @author Geng Zhang
* @date 2019 /2/26
*/
public class BlobUtilsTest {
@@ -42,9 +41,8 @@ public class BlobUtilsTest {
*/
@Test
public void testString2blob() throws SQLException {
- assertNull(BlobUtils.string2blob(null));
assertThat(BlobUtils.string2blob("123abc")).isEqualTo(
- new SerialBlob("123abc".getBytes(Constants.DEFAULT_CHARSET)));
+ new SerialBlob("123abc".getBytes(Charset.forName("UTF-8"))));
}
/**
@@ -54,24 +52,19 @@ public void testString2blob() throws SQLException {
*/
@Test
public void testBlob2string() throws SQLException {
- assertNull(BlobUtils.blob2string(null));
- assertThat(BlobUtils.blob2string(new SerialBlob("123absent".getBytes(Constants.DEFAULT_CHARSET)))).isEqualTo(
+ assertThat(BlobUtils.blob2string(new SerialBlob("123absent".getBytes(Charset.forName("UTF-8"))))).isEqualTo(
"123absent");
}
+ /**
+ * Test input stream 2 string.
+ */
@Test
- void bytes2Blob() throws UnsupportedEncodingException, SQLException {
- assertNull(BlobUtils.bytes2Blob(null));
- byte[] bs = "xxa哈哈dd".getBytes(Constants.DEFAULT_CHARSET_NAME);
- assertThat(BlobUtils.bytes2Blob(bs)).isEqualTo(
- new SerialBlob(bs));
- }
-
- @Test
- void blob2Bytes() throws UnsupportedEncodingException, SQLException {
- assertNull(BlobUtils.blob2Bytes(null));
- byte[] bs = "xxa哈哈dd".getBytes(Constants.DEFAULT_CHARSET_NAME);
- assertThat(BlobUtils.blob2Bytes(new SerialBlob(bs))).isEqualTo(
- bs);
+ @Disabled
+ public void testInputStream2String() {
+ InputStream inputStream = BlobUtilsTest.class.getClassLoader().getResourceAsStream("test.txt");
+ assertThat(BlobUtils.inputStream2String(inputStream)).isEqualTo("abc\n"
+ + ":\"klsdf\n"
+ + "2ks,x:\".,-3sd˚ø≤ø¬≥");
}
}
diff --git a/common/src/test/java/io/seata/common/util/StringUtilsTest.java b/common/src/test/java/io/seata/common/util/StringUtilsTest.java
index c816c0358cb..1eae80462bf 100644
--- a/common/src/test/java/io/seata/common/util/StringUtilsTest.java
+++ b/common/src/test/java/io/seata/common/util/StringUtilsTest.java
@@ -15,15 +15,17 @@
*/
package io.seata.common.util;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.sql.SQLException;
+
+import javax.sql.rowset.serial.SerialBlob;
-import io.seata.common.Constants;
import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertNull;
/**
* The type String utils test.
@@ -46,25 +48,43 @@ public void testIsNullOrEmpty() {
assertThat(StringUtils.isNullOrEmpty(" ")).isFalse();
}
+ /**
+ * Test string 2 blob.
+ *
+ * @throws SQLException the sql exception
+ */
@Test
- public void testInputStream2String() throws IOException {
- assertNull(StringUtils.inputStream2String(null));
- String data = "abc\n"
- + ":\"klsdf\n"
- + "2ks,x:\".,-3sd˚ø≤ø¬≥";
- ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
- assertThat(StringUtils.inputStream2String(inputStream)).isEqualTo(data);
+ public void testString2blob() throws SQLException {
+ assertThat(StringUtils.string2blob(null)).isNull();
+ String[] strs = new String[] {"abc", "", " "};
+ for (String str : strs) {
+ assertThat(StringUtils.string2blob(str)).isEqualTo(new SerialBlob(str.getBytes()));
+ }
}
+ /**
+ * Test blob 2 string.
+ *
+ * @throws SQLException the sql exception
+ */
@Test
- void inputStream2Bytes() {
- assertNull(StringUtils.inputStream2Bytes(null));
- String data = "abc\n"
- + ":\"klsdf\n"
- + "2ks,x:\".,-3sd˚ø≤ø¬≥";
- byte[] bs = data.getBytes(Constants.DEFAULT_CHARSET);
- ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(Constants.DEFAULT_CHARSET));
- assertThat(StringUtils.inputStream2Bytes(inputStream)).isEqualTo(bs);
+ public void testBlob2string() throws SQLException {
+ String[] strs = new String[] {"abc", " "};
+ for (String str : strs) {
+ assertThat(StringUtils.blob2string(new SerialBlob(str.getBytes()))).isEqualTo(str);
+
+ }
+ }
+
+ /**
+ * Test input stream 2 string.
+ */
+ @Test
+ @Disabled
+ public void testInputStream2String() throws IOException {
+ InputStream inputStream = StringUtilsTest.class.getClassLoader().getResourceAsStream("test.txt");
+ assertThat(StringUtils.inputStream2String(inputStream))
+ .isEqualTo("abc\n" + ":\"klsdf\n" + "2ks,x:\".,-3sd˚ø≤ø¬≥");
}
@Test
diff --git a/config/pom.xml b/config/pom.xml
index 36b384ebda6..cfdf735708d 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -32,7 +32,6 @@
seata-config-nacos
seata-config-zk
seata-config-all
- seata-config-etcd3
seata-config-consul
diff --git a/config/seata-config-all/pom.xml b/config/seata-config-all/pom.xml
index 46da42a13db..3cf62928e1b 100644
--- a/config/seata-config-all/pom.xml
+++ b/config/seata-config-all/pom.xml
@@ -41,11 +41,6 @@
seata-config-nacos
${project.version}
-
- ${project.groupId}
- seata-config-etcd3
- ${project.version}
-
${project.groupId}
seata-config-consul
diff --git a/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java b/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
index 0092f4f36ac..7cd509eccdd 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/AbstractConfiguration.java
@@ -15,11 +15,6 @@
*/
package io.seata.config;
-
-import io.seata.common.util.DurationUtil;
-
-import java.time.Duration;
-
/**
* The type Abstract configuration.
*
@@ -66,22 +61,6 @@ public long getLong(String dataId) {
return getLong(dataId, 0L);
}
- @Override
- public Duration getDuration(String dataId) {
- return getDuration(dataId, Duration.ZERO);
- }
-
- @Override
- public Duration getDuration(String dataId, Duration defaultValue) {
- return getDuration(dataId, defaultValue, DEFAULT_CONFIG_TIMEOUT);
- }
-
- @Override
- public Duration getDuration(String dataId, Duration defaultValue, long timeoutMills) {
- String result = getConfig(dataId, String.valueOf(defaultValue.toMillis() + "ms"), timeoutMills);
- return DurationUtil.parse(result);
- }
-
@Override
public boolean getBoolean(String dataId, boolean defaultValue, long timeoutMills) {
String result = getConfig(dataId, String.valueOf(defaultValue), timeoutMills);
diff --git a/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java b/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
index 6f8cf55a4ed..866fddb8d67 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/ConfigType.java
@@ -41,11 +41,7 @@ public enum ConfigType {
/**
* Consul config type
*/
- Consul,
- /**
- * Etcd3 config type
- */
- Etcd3;
+ Consul;
/**
* Gets type.
diff --git a/config/seata-config-core/src/main/java/io/seata/config/Configuration.java b/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
index 67ec8679191..bb3e1a7c18c 100644
--- a/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
+++ b/config/seata-config-core/src/main/java/io/seata/config/Configuration.java
@@ -15,7 +15,6 @@
*/
package io.seata.config;
-import java.time.Duration;
import java.util.List;
/**
@@ -81,33 +80,6 @@ public interface Configuration {
*/
long getLong(String dataId);
- /**
- * Gets duration.
- *
- * @param dataId
- * @return the duration
- */
- Duration getDuration(String dataId);
-
- /**
- * Gets duration.
- *
- * @param dataId
- * @param defaultValue
- * @return the duration
- */
- Duration getDuration(String dataId, Duration defaultValue);
-
- /**
- * Gets duration.
- *
- * @param dataId
- * @param defaultValue
- * @param timeoutMills
- * @return he duration
- */
- Duration getDuration(String dataId, Duration defaultValue, long timeoutMills);
-
/**
* Gets boolean.
*
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 cd5ea345d5c..0b802b3d344 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
@@ -17,6 +17,8 @@
import io.seata.common.exception.NotSupportYetException;
import io.seata.common.loader.EnhancedServiceLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Objects;
@@ -24,9 +26,10 @@
* The type Configuration factory.
*
* @author jimin.jm @alibaba-inc.com
- * @author Geng Zhang
+ * @date 2018 /12/24
*/
public final class ConfigurationFactory {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationFactory.class);
private static final String REGISTRY_CONF = "registry.conf";
/**
* The constant FILE_INSTANCE.
@@ -35,33 +38,20 @@ public final class ConfigurationFactory {
private static final String NAME_KEY = "name";
private static final String FILE_TYPE = "file";
- private static volatile Configuration CONFIG_INSTANCE = null;
-
/**
* Gets instance.
*
* @return the instance
*/
public static Configuration getInstance() {
- if (CONFIG_INSTANCE == null) {
- synchronized (Configuration.class) {
- if (CONFIG_INSTANCE == null) {
- CONFIG_INSTANCE = buildConfiguration();
- }
- }
- }
- return CONFIG_INSTANCE;
- }
-
- private static Configuration buildConfiguration() {
ConfigType configType = null;
String configTypeName = null;
try {
configTypeName = FILE_INSTANCE.getConfig(ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
+ ConfigurationKeys.FILE_ROOT_TYPE);
configType = ConfigType.getType(configTypeName);
- } catch (Exception e) {
- throw new NotSupportYetException("not support register type: " + configTypeName, e);
+ } catch (Exception exx) {
+ throw new NotSupportYetException("not support register type: " + configTypeName);
}
if (ConfigType.File == configType) {
String pathDataId = ConfigurationKeys.FILE_ROOT_CONFIG + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
diff --git a/config/seata-config-core/src/main/resources/file.conf b/config/seata-config-core/src/main/resources/file.conf
index a166f8d5c5c..dc09514d367 100644
--- a/config/seata-config-core/src/main/resources/file.conf
+++ b/config/seata-config-core/src/main/resources/file.conf
@@ -69,8 +69,4 @@ client {
retry.times = 30
}
report.retry.count = 5
-}
-
-transaction {
- undo.data.validation = true
-}
+}
\ No newline at end of file
diff --git a/config/seata-config-core/src/main/resources/registry.conf b/config/seata-config-core/src/main/resources/registry.conf
index 5115876d916..1d6c3598256 100644
--- a/config/seata-config-core/src/main/resources/registry.conf
+++ b/config/seata-config-core/src/main/resources/registry.conf
@@ -45,7 +45,7 @@ registry {
}
config {
- # file、nacos 、apollo、zk、consul、etcd3
+ # file、nacos 、apollo、zk、consul
type = "file"
nacos {
@@ -65,9 +65,6 @@ config {
session.timeout = 6000
connect.timeout = 2000
}
- etcd3 {
- serverAddr = "http://localhost:2379"
- }
file {
name = "file.conf"
}
diff --git a/config/seata-config-etcd3/pom.xml b/config/seata-config-etcd3/pom.xml
deleted file mode 100644
index beb590dfffe..00000000000
--- a/config/seata-config-etcd3/pom.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
- io.seata
- seata-config
- ${revision}
-
- 4.0.0
- seata-config-etcd3
- seata-config-etcd3 ${project.version}
-
-
-
- io.seata
- seata-config-core
- ${project.parent.version}
-
-
- io.etcd
- jetcd-core
-
-
- com.google.guava
- guava
-
-
-
-
- com.google.guava
- guava
-
-
-
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/etcd/EtcdConfiguration.java
deleted file mode 100644
index 6eed7d53035..00000000000
--- a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfiguration.java
+++ /dev/null
@@ -1,318 +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.config.etcd;
-
-import io.etcd.jetcd.ByteSequence;
-import io.etcd.jetcd.Client;
-import io.etcd.jetcd.KeyValue;
-import io.etcd.jetcd.Watch;
-import io.etcd.jetcd.kv.DeleteResponse;
-import io.etcd.jetcd.kv.GetResponse;
-import io.etcd.jetcd.kv.PutResponse;
-import io.etcd.jetcd.kv.TxnResponse;
-import io.etcd.jetcd.op.Cmp;
-import io.etcd.jetcd.op.CmpTarget;
-import io.etcd.jetcd.op.Op;
-import io.etcd.jetcd.options.PutOption;
-import io.etcd.jetcd.watch.WatchResponse;
-import io.seata.common.exception.ShouldNeverHappenException;
-import io.seata.common.thread.NamedThreadFactory;
-import io.seata.common.util.CollectionUtils;
-import io.seata.config.AbstractConfiguration;
-import io.seata.config.ConfigChangeListener;
-import io.seata.config.ConfigFuture;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CompletableFuture;
-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 static io.netty.util.CharsetUtil.UTF_8;
-import static io.seata.config.ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR;
-import static io.seata.config.ConfigurationKeys.FILE_ROOT_CONFIG;
-
-/**
- * @author xingfudeshi@gmail.com
- * @date 2019/05/10
- */
-public class EtcdConfiguration extends AbstractConfiguration {
- private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfiguration.class);
- private static volatile EtcdConfiguration instance;
- private static volatile Client client;
-
- private static final Configuration FILE_CONFIG = ConfigurationFactory.FILE_INSTANCE;
- private static final String SERVER_ADDR_KEY = "serverAddr";
- private static final String CONFIG_TYPE = "etcd3";
- private static final String FILE_CONFIG_KEY_PREFIX = FILE_ROOT_CONFIG + FILE_CONFIG_SPLIT_CHAR + CONFIG_TYPE + FILE_CONFIG_SPLIT_CHAR;
- private static final int THREAD_POOL_NUM = 1;
- private static final int MAP_INITIAL_CAPACITY = 8;
- private static ExecutorService etcdConfigExecutor = null;
- private static ExecutorService etcdNotifierExecutor = null;
- private static ConcurrentMap> configListenersMap = null;
- private static ConcurrentHashMap> configChangeNotifiersMap = null;
-
- private static final long VERSION_NOT_EXIST = 0;
-
- private EtcdConfiguration() {
- }
-
- /**
- * get instance
- *
- * @return
- */
- public static EtcdConfiguration getInstance() {
- if (null == instance) {
- synchronized (EtcdConfiguration.class) {
- if (null == instance) {
- etcdConfigExecutor = new ThreadPoolExecutor(THREAD_POOL_NUM, THREAD_POOL_NUM,
- Integer.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("etcd-config-executor", THREAD_POOL_NUM));
- etcdNotifierExecutor = new ThreadPoolExecutor(THREAD_POOL_NUM, THREAD_POOL_NUM,
- Integer.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new NamedThreadFactory("etcd-config-notifier-executor", THREAD_POOL_NUM));
- configListenersMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
- configChangeNotifiersMap = new ConcurrentHashMap<>(MAP_INITIAL_CAPACITY);
- instance = new EtcdConfiguration();
- }
- }
- }
- return instance;
- }
-
-
- @Override
- public String getTypeName() {
- return CONFIG_TYPE;
- }
-
- @Override
- public String getConfig(String dataId, String defaultValue, long timeoutMills) {
- ConfigFuture configFuture = new ConfigFuture(dataId, defaultValue, ConfigFuture.ConfigOperation.GET, timeoutMills);
- etcdConfigExecutor.execute(() -> {
- complete(getClient().getKVClient().get(ByteSequence.from(dataId, UTF_8)), configFuture);
- });
- return (String) configFuture.get();
- }
-
- @Override
- public boolean putConfig(String dataId, String content, long timeoutMills) {
- ConfigFuture configFuture = new ConfigFuture(dataId, content, ConfigFuture.ConfigOperation.PUT, timeoutMills);
- etcdConfigExecutor.execute(() -> {
- complete(getClient().getKVClient().put(ByteSequence.from(dataId, UTF_8), ByteSequence.from(content, UTF_8)), configFuture);
- });
- return (Boolean) configFuture.get();
- }
-
- @Override
- public boolean putConfigIfAbsent(String dataId, String content, long timeoutMills) {
- ConfigFuture configFuture = new ConfigFuture(dataId, content, ConfigFuture.ConfigOperation.PUTIFABSENT, timeoutMills);
- etcdConfigExecutor.execute(() -> {
- //use etcd transaction to ensure the atomic operation
- complete(client.getKVClient().txn()
- //whether the key exists
- .If(new Cmp(ByteSequence.from(dataId, UTF_8), Cmp.Op.EQUAL, CmpTarget.version(VERSION_NOT_EXIST)))
- //not exist,then will create
- .Then(Op.put(ByteSequence.from(dataId, UTF_8), ByteSequence.from(content, UTF_8), PutOption.DEFAULT))
- .commit(), configFuture);
- });
- return (Boolean) configFuture.get();
- }
-
- @Override
- public boolean removeConfig(String dataId, long timeoutMills) {
- ConfigFuture configFuture = new ConfigFuture(dataId, null, ConfigFuture.ConfigOperation.REMOVE, timeoutMills);
- etcdConfigExecutor.execute(() -> {
- complete(getClient().getKVClient().delete(ByteSequence.from(dataId, UTF_8)), configFuture);
- });
- return (Boolean) configFuture.get();
- }
-
- @Override
- public void addConfigListener(String dataId, ConfigChangeListener listener) {
- configListenersMap.putIfAbsent(dataId, new ArrayList<>());
- configChangeNotifiersMap.putIfAbsent(dataId, new ArrayList<>());
- ConfigChangeNotifier configChangeNotifier = new ConfigChangeNotifier(dataId, listener);
- configChangeNotifiersMap.get(dataId).add(configChangeNotifier);
- if (null != listener.getExecutor()) {
- listener.getExecutor().submit(configChangeNotifier);
- } else {
- etcdNotifierExecutor.submit(configChangeNotifier);
- }
- }
-
- @Override
- public void removeConfigListener(String dataId, ConfigChangeListener listener) {
- List configChangeListeners = getConfigListeners(dataId);
- if (configChangeListeners == null) {
- return;
- }
- List newChangeListenerList = new ArrayList<>();
- for (ConfigChangeListener changeListener : configChangeListeners) {
- if (!changeListener.equals(listener)) {
- newChangeListenerList.add(changeListener);
- }
- }
- configListenersMap.put(dataId, newChangeListenerList);
- if (null != listener.getExecutor()) {
- listener.getExecutor().shutdownNow();
- }
- //remove and stop the configChangeNotifier
- List configChangeNotifiers = configChangeNotifiersMap.get(dataId);
- List newConfigChangeNotifiers = new ArrayList<>();
- for (ConfigChangeNotifier configChangeNotifier : configChangeNotifiers) {
- if (!listener.equals(configChangeNotifier.getListener())) {
- newConfigChangeNotifiers.add(configChangeNotifier);
- } else {
- configChangeNotifier.stop();
- }
- }
- configChangeNotifiersMap.put(dataId, newConfigChangeNotifiers);
- }
-
- @Override
- public List getConfigListeners(String dataId) {
- return configListenersMap.get(dataId);
- }
-
- /**
- * get client
- *
- * @return client
- */
- private static Client getClient() {
- if (null == client) {
- synchronized (EtcdConfiguration.class) {
- if (null == client) {
- client = Client.builder().endpoints(FILE_CONFIG.getConfig(FILE_CONFIG_KEY_PREFIX + SERVER_ADDR_KEY)).build();
- }
- }
- }
- return client;
- }
-
- /**
- * complete the future
- *
- * @param completableFuture
- * @param configFuture
- * @param
- */
- private void complete(CompletableFuture completableFuture, ConfigFuture configFuture) {
- try {
- T response = completableFuture.get();
- if (response instanceof GetResponse) {
- List keyValues = ((GetResponse) response).getKvs();
- if (CollectionUtils.isNotEmpty(keyValues)) {
- ByteSequence value = keyValues.get(0).getValue();
- if (null != value) {
- configFuture.setResult(value.toString(UTF_8));
- }
- }
- } else if (response instanceof PutResponse) {
- configFuture.setResult(Boolean.TRUE);
- } else if (response instanceof TxnResponse) {
- boolean result = ((TxnResponse) response).isSucceeded();
- //create key if file does not exist)
- if (result) {
- configFuture.setResult(Boolean.TRUE);
- }
- } else if (response instanceof DeleteResponse) {
- configFuture.setResult(Boolean.TRUE);
- } else {
- throw new ShouldNeverHappenException("unsupported response type");
- }
- } catch (Exception e) {
- LOGGER.error("error occurred while completing the future{}", e.getMessage());
- }
- }
-
- /**
- * the type config change notifier
- */
- private static class ConfigChangeNotifier implements Runnable {
- private final String dataId;
- private final ConfigChangeListener listener;
- private Watch.Watcher watcher;
-
- ConfigChangeNotifier(String dataId, ConfigChangeListener listener) {
- this.dataId = dataId;
- this.listener = listener;
- }
-
- /**
- * get the listener
- *
- * @return ConfigChangeListener
- */
- ConfigChangeListener getListener() {
- return this.listener;
- }
-
- @Override
- public void run() {
- Watch watchClient = getClient().getWatchClient();
- watcher = watchClient.watch(ByteSequence.from(dataId, UTF_8), new Watch.Listener() {
- @Override
- public void onNext(WatchResponse response) {
- notifyListeners();
- }
-
- @Override
- public void onError(Throwable throwable) {
-
- }
-
- @Override
- public void onCompleted() {
-
- }
- });
- }
-
- /**
- * notify listeners
- */
- private void notifyListeners() {
- try {
- GetResponse getResponse = getClient().getKVClient().get(ByteSequence.from(dataId, UTF_8)).get();
- List keyValues = getResponse.getKvs();
- if (CollectionUtils.isNotEmpty(keyValues)) {
- for (ConfigChangeListener listener : configListenersMap.get(this.dataId)) {
- listener.receiveConfigInfo(keyValues.get(0).getValue().toString(UTF_8));
- }
- }
- } catch (Exception e) {
- LOGGER.error("error occurred while getting value{}", e.getMessage());
- }
- }
-
-
- /**
- * stop the notifier
- */
- public void stop() {
- this.watcher.close();
- }
- }
-}
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/etcd/EtcdConfigurationProvider.java
deleted file mode 100644
index acb7e28db96..00000000000
--- a/config/seata-config-etcd3/src/main/java/io/seata/config/etcd/EtcdConfigurationProvider.java
+++ /dev/null
@@ -1,32 +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.config.etcd;
-
-import io.seata.common.loader.LoadLevel;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationProvider;
-
-/**
- * @author xingfudeshi@gmail.com
- * @date 2019/04/12
- */
-@LoadLevel(name = "Etcd3", order = 1)
-public class EtcdConfigurationProvider implements ConfigurationProvider {
- @Override
- public Configuration provide() {
- return EtcdConfiguration.getInstance();
- }
-}
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
deleted file mode 100644
index ce01ac19760..00000000000
--- a/config/seata-config-etcd3/src/main/resources/META-INF/services/io.seata.config.ConfigurationProvider
+++ /dev/null
@@ -1 +0,0 @@
-io.seata.config.etcd.EtcdConfigurationProvider
\ No newline at end of file
diff --git a/core/pom.xml b/core/pom.xml
index 9670f9fd495..a6a71f8e60d 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -55,17 +55,6 @@
commons-pool
commons-pool
-
- commons-dbcp
- commons-dbcp
- test
-
-
- com.h2database
- h2
- test
-
-
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 dc6f93fef8c..4df7b3f11c6 100644
--- a/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
+++ b/core/src/main/java/io/seata/core/constants/ConfigurationKeys.java
@@ -92,111 +92,4 @@ public class ConfigurationKeys {
* The constant CLIENT_REPORT_RETRY_COUNT.
*/
public static final String CLIENT_REPORT_RETRY_COUNT = CLIENT_PREFIX + "report.retry.count";
-
- /**
- * The constant STORE_DB_GLOBAL_TABLE.
- */
- public static final String STORE_DB_GLOBAL_TABLE = "store.db.global.table";
-
- /**
- * The constant STORE_DB_BRANCH_TABLE.
- */
- public static final String STORE_DB_BRANCH_TABLE = "store.db.branch.table";
-
- /**
- * The constant STORE_DB_GLOBAL_DEFAULT_TABLE.
- */
- public static final String STORE_DB_GLOBAL_DEFAULT_TABLE = "global_table";
-
- /**
- * The constant STORE_DB_BRANCH_DEFAULT_TABLE.
- */
- public static final String STORE_DB_BRANCH_DEFAULT_TABLE = "branch_table";
-
- /**
- * The constant STORE_DB_DATASOURCE_TYPE.
- */
- public static final String STORE_DB_DATASOURCE_TYPE = "store.db.datasource";
-
-
- /**
- * The constant STORE_DB_TYPE.
- */
- public static final String STORE_DB_TYPE = "store.db.db-type";
-
- /**
- * The constant STORE_DB_URL.
- */
- public static final String STORE_DB_URL = "store.db.url";
-
- /**
- * The constant STORE_DB_USER.
- */
- public static final String STORE_DB_USER = "store.db.user";
-
- /**
- * The constant STORE_DB_PASSWORD.
- */
- public static final String STORE_DB_PASSWORD = "store.db.password";
-
- /**
- * The constant STORE_DB_MIN_CONN.
- */
- public static final String STORE_DB_MIN_CONN = "store.db.min-conn";
-
- /**
- * The constant STORE_DB_MAX_CONN.
- */
- public static final String STORE_DB_MAX_CONN = "store.db.max-conn";
-
- /**
- * The constant STORE_DB_LOG_QUERY_LIMIT.
- */
- public static final String STORE_DB_LOG_QUERY_LIMIT = "store.db.query-limit";
-
- /**
- * The constant LOCK_MODE.
- */
- public static final String LOCK_MODE = "lock.mode";
-
- /**
- * The constant LOCK_DB_TABLE.
- */
- public static final String LOCK_DB_TABLE = "lock.db.lock-table";
-
- /**
- * The constant LOCK_DB_DEFAULT_TABLE.
- */
- public static final String LOCK_DB_DEFAULT_TABLE = "lock_table";
-
- /**
- * The constant COMMITING_RETRY_DELAY.
- */
- public static final String COMMITING_RETRY_DELAY = "recovery.committing-retry-delay";
-
- /**
- * The constant ASYN_COMMITING_RETRY_DELAY.
- */
- public static final String ASYN_COMMITING_RETRY_DELAY = "recovery.asyn-committing-retry-delay";
-
- /**
- * The constant ROLLBACKING_RETRY_DELAY.
- */
- public static final String ROLLBACKING_RETRY_DELAY = "recovery.rollbacking-retry-delay";
-
- /**
- * The constant TIMEOUT_RETRY_DELAY.
- */
- public static final String TIMEOUT_RETRY_DELAY = "recovery.timeout-retry-delay";
-
-
- /**
- * The constant TRANSACTION_PREFIX.
- */
- public static final String TRANSACTION_PREFIX = "transaction.";
-
- /**
- * The constant RM_DATASOURCE_UNOD_VALIDATION.
- */
- public static final String TRANSACTION_UNOD_DATA_VALIDATION = TRANSACTION_PREFIX + "undo.data.validation";
}
diff --git a/core/src/main/java/io/seata/core/constants/DBType.java b/core/src/main/java/io/seata/core/constants/DBType.java
deleted file mode 100644
index cdb0174b985..00000000000
--- a/core/src/main/java/io/seata/core/constants/DBType.java
+++ /dev/null
@@ -1,93 +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.constants;
-
-import io.seata.common.util.StringUtils;
-
-/**
- * database type
- *
- * @author zhangsen
- * @data 2019 /4/2
- */
-public enum DBType {
-
- /**
- * Mysql db type.
- */
- MYSQL,
-
- /**
- * Oracle db type.
- */
- ORACLE,
-
- /**
- * Db 2 db type.
- */
- DB2,
-
- /**
- * Sqlserver db type.
- */
- SQLSERVER,
-
- /**
- * Sybaee db type.
- */
- SYBAEE,
-
- /**
- * H2 db type.
- */
- H2,
-
- /**
- * Sqlite db type.
- */
- SQLITE,
-
- /**
- * Access db type.
- */
- ACCESS,
-
- /**
- * Postgresql db type.
- */
- POSTGRESQL,
-
- /**
- * Oceanbase db type.
- */
- OCEANBASE;
-
- /**
- * Valueof db type.
- *
- * @param dbType the db type
- * @return the db type
- */
- public static DBType valueof (String dbType){
- for(DBType dt : values()){
- if(StringUtils.equalsIgnoreCase(dt.name(),dbType)){
- return dt;
- }
- }
- throw new IllegalArgumentException("unknown dbtype:" + dbType);
- }
-
-}
\ No newline at end of file
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 a8501be705a..9aa741dd28d 100644
--- a/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
+++ b/core/src/main/java/io/seata/core/exception/AbstractExceptionHandler.java
@@ -15,8 +15,6 @@
*/
package io.seata.core.exception;
-import io.seata.config.Configuration;
-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;
@@ -28,11 +26,6 @@
*/
public abstract class AbstractExceptionHandler {
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
/**
* The interface Callback.
*
diff --git a/core/src/main/java/io/seata/core/lock/AbstractLocker.java b/core/src/main/java/io/seata/core/lock/AbstractLocker.java
deleted file mode 100644
index ddb0dd073ef..00000000000
--- a/core/src/main/java/io/seata/core/lock/AbstractLocker.java
+++ /dev/null
@@ -1,85 +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.lock;
-
-import io.seata.common.util.CollectionUtils;
-import io.seata.core.store.LockDO;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The type Abstract locker.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-public abstract class AbstractLocker implements Locker {
-
- /**
- * The constant LOGGER.
- */
- protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLocker.class);
-
- /**
- * The constant LOCK_SPLIT.
- */
- protected static final String LOCK_SPLIT = "^^^";
-
- /**
- * Convert to lock do list.
- *
- * @param locks the locks
- * @return the list
- */
- protected List convertToLockDO(List locks){
- List lockDOs = new ArrayList<>();
- if(CollectionUtils.isEmpty(locks)){
- return lockDOs;
- }
- for(RowLock rowLock : locks){
- LockDO lockDO = new LockDO();
- lockDO.setBranchId(rowLock.getBranchId());
- lockDO.setPk(rowLock.getPk());
- lockDO.setResourceId(rowLock.getResourceId());
- lockDO.setRowKey(getRowKey(rowLock.getResourceId(), rowLock.getTableName(), rowLock.getPk()));
- lockDO.setXid(rowLock.getXid());
- lockDO.setTransactionId(rowLock.getTransactionId());
- lockDO.setTableName(rowLock.getTableName());
- lockDOs.add(lockDO);
- }
- return lockDOs;
- }
-
- /**
- * Get row key string.
- *
- * @param resourceId the resource id
- * @param tableName the table name
- * @param pk the pk
- * @return the string
- */
- protected String getRowKey(String resourceId, String tableName, String pk){
- return new StringBuilder().append(resourceId).append(LOCK_SPLIT).append(tableName).append(LOCK_SPLIT).append(pk).toString();
- }
-
- @Override
- public void cleanAllLocks() {
-
- }
-}
diff --git a/core/src/main/java/io/seata/core/lock/LocalDBLocker.java b/core/src/main/java/io/seata/core/lock/LocalDBLocker.java
deleted file mode 100644
index c342e8f6ecf..00000000000
--- a/core/src/main/java/io/seata/core/lock/LocalDBLocker.java
+++ /dev/null
@@ -1,42 +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.lock;
-
-import java.util.List;
-
-/**
- * The type Local db locker.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-public class LocalDBLocker extends AbstractLocker {
-
- @Override
- public boolean acquireLock(List rowLock) {
- return false;
- }
-
- @Override
- public boolean releaseLock(List rowLock) {
- return false;
- }
-
- @Override
- public boolean isLockable(List rowLock) {
- return false;
- }
-}
diff --git a/core/src/main/java/io/seata/core/lock/LockMode.java b/core/src/main/java/io/seata/core/lock/LockMode.java
deleted file mode 100644
index f1a11d0b9ea..00000000000
--- a/core/src/main/java/io/seata/core/lock/LockMode.java
+++ /dev/null
@@ -1,37 +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.lock;
-
-/**
- * lock mode
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-public enum LockMode {
-
- /**
- * store the lock in memory of server
- */
- MEMORY,
-
- /**
- * store the lock in db of server
- */
- DB;
-
-
-}
diff --git a/core/src/main/java/io/seata/core/lock/Locker.java b/core/src/main/java/io/seata/core/lock/Locker.java
deleted file mode 100644
index 8990699d317..00000000000
--- a/core/src/main/java/io/seata/core/lock/Locker.java
+++ /dev/null
@@ -1,59 +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.lock;
-
-import java.util.List;
-
-/**
- * The interface Locker.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-public interface Locker {
-
- /**
- * Acquire lock boolean.
- *
- * @param rowLock the row lock
- * @return the boolean
- */
- boolean acquireLock(List rowLock) ;
-
- /**
- * Un lock boolean.
- *
- * @param rowLock the row lock
- * @return the boolean
- */
- boolean releaseLock(List rowLock);
-
- /**
- * Is lockable boolean.
- *
- * @param rowLock the row lock
- * @return the boolean
- */
- boolean isLockable(List rowLock);
-
- /**
- * Clean all locks boolean.
- *
- * @return the boolean
- */
- void cleanAllLocks();
-}
-
diff --git a/core/src/main/java/io/seata/core/lock/RowLock.java b/core/src/main/java/io/seata/core/lock/RowLock.java
deleted file mode 100644
index 9675cb9011d..00000000000
--- a/core/src/main/java/io/seata/core/lock/RowLock.java
+++ /dev/null
@@ -1,193 +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.lock;
-
-import io.seata.common.util.StringUtils;
-
-/**
- * The type Row lock.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-public class RowLock {
-
- private String xid;
-
- private Long transactionId;
-
- private Long branchId;
-
- private String resourceId;
-
- private String tableName;
-
- private String pk;
-
- private String rowKey;
-
- private String feature;
-
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
- /**
- * Gets transaction id.
- *
- * @return the transaction id
- */
- public Long getTransactionId() {
- return transactionId;
- }
-
- /**
- * Sets transaction id.
- *
- * @param transactionId the transaction id
- */
- public void setTransactionId(Long transactionId) {
- this.transactionId = transactionId;
- }
-
- /**
- * Gets branch id.
- *
- * @return the branch id
- */
- public Long getBranchId() {
- return branchId;
- }
-
- /**
- * Sets branch id.
- *
- * @param branchId the branch id
- */
- public void setBranchId(Long branchId) {
- this.branchId = branchId;
- }
-
- /**
- * Gets resource id.
- *
- * @return the resource id
- */
- public String getResourceId() {
- return resourceId;
- }
-
- /**
- * Sets resource id.
- *
- * @param resourceId the resource id
- */
- public void setResourceId(String resourceId) {
- this.resourceId = resourceId;
- }
-
- /**
- * Gets table name.
- *
- * @return the table name
- */
- public String getTableName() {
- return tableName;
- }
-
- /**
- * Sets table name.
- *
- * @param tableName the table name
- */
- public void setTableName(String tableName) {
- this.tableName = tableName;
- }
-
- /**
- * Gets pk.
- *
- * @return the pk
- */
- public String getPk() {
- return pk;
- }
-
- /**
- * Sets pk.
- *
- * @param pk the pk
- */
- public void setPk(String pk) {
- this.pk = pk;
- }
-
- /**
- * Gets row key.
- *
- * @return the row key
- */
- public String getRowKey() {
- return rowKey;
- }
-
- /**
- * Sets row key.
- *
- * @param rowKey the row key
- */
- public void setRowKey(String rowKey) {
- this.rowKey = rowKey;
- }
-
- /**
- * Gets feature.
- *
- * @return the feature
- */
- public String getFeature() {
- return feature;
- }
-
- /**
- * Sets feature.
- *
- * @param feature the feature
- */
- public void setFeature(String feature) {
- this.feature = feature;
- }
-
- @Override
- public String toString(){
- return StringUtils.toString(this);
- }
-}
-
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 60ec91b978d..e6f3dd07e09 100644
--- a/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
+++ b/core/src/main/java/io/seata/core/protocol/AbstractMessage.java
@@ -18,7 +18,6 @@
import java.io.Serializable;
import java.nio.charset.Charset;
-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;
@@ -153,7 +152,7 @@ public abstract class AbstractMessage implements MessageCodec, Serializable {
/**
* The constant UTF8.
*/
- protected static final Charset UTF8 = Constants.DEFAULT_CHARSET;
+ protected static final Charset UTF8 = Charset.forName("utf-8");
/**
* The Ctx.
*/
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 de8dcf726bd..3f5a40470e7 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.0";
+ public static final String CURRENT = "0.5.2";
/**
* The constant VERSION_MAP.
diff --git a/core/src/main/java/io/seata/core/rpc/ChannelManager.java b/core/src/main/java/io/seata/core/rpc/ChannelManager.java
index 9de2904e93e..d63086ea251 100644
--- a/core/src/main/java/io/seata/core/rpc/ChannelManager.java
+++ b/core/src/main/java/io/seata/core/rpc/ChannelManager.java
@@ -29,6 +29,7 @@
import io.seata.core.protocol.RegisterRMRequest;
import io.seata.core.protocol.RegisterTMRequest;
import io.seata.core.protocol.Version;
+import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import io.seata.core.rpc.netty.NettyPoolKey;
diff --git a/core/src/main/java/io/seata/core/rpc/RpcContext.java b/core/src/main/java/io/seata/core/rpc/RpcContext.java
index 6ba531eb16a..b605b72d067 100644
--- a/core/src/main/java/io/seata/core/rpc/RpcContext.java
+++ b/core/src/main/java/io/seata/core/rpc/RpcContext.java
@@ -23,6 +23,7 @@
import java.util.concurrent.ConcurrentMap;
import io.seata.common.Constants;
+import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import io.seata.core.rpc.netty.NettyPoolKey;
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 d5bf8625ca7..44c33d31fdf 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
@@ -35,7 +35,12 @@
import io.seata.common.exception.FrameworkErrorCode;
import io.seata.common.exception.FrameworkException;
import io.seata.common.thread.NamedThreadFactory;
+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 io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelFuture;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java b/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
index 24c7a0f7c51..2ae97ced878 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/NettyClientConfig.java
@@ -15,6 +15,8 @@
*/
package io.seata.core.rpc.netty;
+import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
+
import io.netty.channel.Channel;
/**
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 9d69006f9fb..db29b780465 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
@@ -21,6 +21,7 @@
import io.seata.common.util.NetUtil;
import io.seata.core.protocol.RegisterRMResponse;
import io.seata.core.protocol.RegisterTMResponse;
+import io.seata.core.rpc.netty.NettyPoolKey.TransactionRole;
import io.netty.channel.Channel;
import org.apache.commons.pool.KeyedPoolableObjectFactory;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java b/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
index ef0afc75f63..d078a4df0da 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RegisterCheckAuthHandler.java
@@ -15,6 +15,8 @@
*/
package io.seata.core.rpc.netty;
+import io.seata.core.protocol.RegisterRMRequest;
+import io.seata.core.protocol.RegisterTMRequest;
import io.seata.core.protocol.RegisterRMRequest;
import io.seata.core.protocol.RegisterTMRequest;
diff --git a/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java b/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
index 98ba76fad03..42a9eedbac5 100644
--- a/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
+++ b/core/src/main/java/io/seata/core/rpc/netty/RegisterMsgListener.java
@@ -15,6 +15,8 @@
*/
package io.seata.core.rpc.netty;
+import io.seata.core.protocol.AbstractMessage;
+
import io.netty.channel.Channel;
import io.seata.core.protocol.AbstractMessage;
diff --git a/core/src/main/java/io/seata/core/store/BranchTransactionDO.java b/core/src/main/java/io/seata/core/store/BranchTransactionDO.java
deleted file mode 100644
index 63c784daf6c..00000000000
--- a/core/src/main/java/io/seata/core/store/BranchTransactionDO.java
+++ /dev/null
@@ -1,277 +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.store;
-
-
-import io.seata.common.util.StringUtils;
-import io.seata.core.model.BranchStatus;
-
-import java.util.Date;
-
-/**
- * branch transaction data object
- *
- * @author zhangsen
- * @data 2019 /3/26
- */
-public class BranchTransactionDO {
-
- private String xid;
-
- private long transactionId;
-
- private long branchId;
-
- private String resourceGroupId;
-
- private String resourceId;
-
- private String lockKey;
-
- private String branchType;
-
- private int status = BranchStatus.Unknown.getCode();
-
- private String clientId;
-
- private String applicationData;
-
- private Date gmtCreate;
-
- private Date gmtModified;
-
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
- /**
- * Gets transaction id.
- *
- * @return the transaction id
- */
- public long getTransactionId() {
- return transactionId;
- }
-
- /**
- * Sets transaction id.
- *
- * @param transactionId the transaction id
- */
- public void setTransactionId(long transactionId) {
- this.transactionId = transactionId;
- }
-
- /**
- * Gets branch id.
- *
- * @return the branch id
- */
- public long getBranchId() {
- return branchId;
- }
-
- /**
- * Sets branch id.
- *
- * @param branchId the branch id
- */
- public void setBranchId(long branchId) {
- this.branchId = branchId;
- }
-
- /**
- * Gets resource group id.
- *
- * @return the resource group id
- */
- public String getResourceGroupId() {
- return resourceGroupId;
- }
-
- /**
- * Sets resource group id.
- *
- * @param resourceGroupId the resource group id
- */
- public void setResourceGroupId(String resourceGroupId) {
- this.resourceGroupId = resourceGroupId;
- }
-
- /**
- * Gets resource id.
- *
- * @return the resource id
- */
- public String getResourceId() {
- return resourceId;
- }
-
- /**
- * Sets resource id.
- *
- * @param resourceId the resource id
- */
- public void setResourceId(String resourceId) {
- this.resourceId = resourceId;
- }
-
- /**
- * Gets lock key.
- *
- * @return the lock key
- */
- public String getLockKey() {
- return lockKey;
- }
-
- /**
- * Sets lock key.
- *
- * @param lockKey the lock key
- */
- public void setLockKey(String lockKey) {
- this.lockKey = lockKey;
- }
-
- /**
- * Gets branch type.
- *
- * @return the branch type
- */
- public String getBranchType() {
- return branchType;
- }
-
- /**
- * Sets branch type.
- *
- * @param branchType the branch type
- */
- public void setBranchType(String branchType) {
- this.branchType = branchType;
- }
-
- /**
- * Gets status.
- *
- * @return the status
- */
- public int getStatus() {
- return status;
- }
-
- /**
- * Sets status.
- *
- * @param status the status
- */
- public void setStatus(int status) {
- this.status = status;
- }
-
- /**
- * Gets client id.
- *
- * @return the client id
- */
- public String getClientId() {
- return clientId;
- }
-
- /**
- * Sets client id.
- *
- * @param clientId the client id
- */
- public void setClientId(String clientId) {
- this.clientId = clientId;
- }
-
- /**
- * Gets application data.
- *
- * @return the application data
- */
- public String getApplicationData() {
- return applicationData;
- }
-
- /**
- * Sets application data.
- *
- * @param applicationData the application data
- */
- public void setApplicationData(String applicationData) {
- this.applicationData = applicationData;
- }
-
- /**
- * Gets gmt create.
- *
- * @return the gmt create
- */
- public Date getGmtCreate() {
- return gmtCreate;
- }
-
- /**
- * Sets gmt create.
- *
- * @param gmtCreate the gmt create
- */
- public void setGmtCreate(Date gmtCreate) {
- this.gmtCreate = gmtCreate;
- }
-
- /**
- * Gets gmt modified.
- *
- * @return the gmt modified
- */
- public Date getGmtModified() {
- return gmtModified;
- }
-
- /**
- * Sets gmt modified.
- *
- * @param gmtModified the gmt modified
- */
- public void setGmtModified(Date gmtModified) {
- this.gmtModified = gmtModified;
- }
-
- @Override
- public String toString(){
- return StringUtils.toString(this);
- }
-
-}
diff --git a/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java b/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java
deleted file mode 100644
index 74c5e9ae13f..00000000000
--- a/core/src/main/java/io/seata/core/store/GlobalTransactionDO.java
+++ /dev/null
@@ -1,256 +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.store;
-
-
-import io.seata.common.util.StringUtils;
-
-import java.util.Date;
-
-/**
- * Global Transaction data object
- *
- * @author zhangsen
- * @data 2019 /3/26
- */
-public class GlobalTransactionDO {
-
- private String xid;
-
- private long transactionId;
-
- private int status;
-
- private String applicationId;
-
- private String transactionServiceGroup;
-
- private String transactionName;
-
- private int timeout;
-
- private long beginTime;
-
- private String applicationData;
-
- private Date gmtCreate;
-
- private Date gmtModified;
-
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
- /**
- * Gets status.
- *
- * @return the status
- */
- public int getStatus() {
- return status;
- }
-
- /**
- * Sets status.
- *
- * @param status the status
- */
- public void setStatus(int status) {
- this.status = status;
- }
-
- /**
- * Gets application id.
- *
- * @return the application id
- */
- public String getApplicationId() {
- return applicationId;
- }
-
- /**
- * Sets application id.
- *
- * @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.
- *
- * @param transactionServiceGroup the transaction service group
- */
- public void setTransactionServiceGroup(String transactionServiceGroup) {
- this.transactionServiceGroup = transactionServiceGroup;
- }
-
- /**
- * Gets transaction name.
- *
- * @return the transaction name
- */
- public String getTransactionName() {
- return transactionName;
- }
-
- /**
- * Sets transaction name.
- *
- * @param transactionName the transaction name
- */
- public void setTransactionName(String transactionName) {
- this.transactionName = transactionName;
- }
-
- /**
- * Gets timeout.
- *
- * @return the timeout
- */
- public int getTimeout() {
- return timeout;
- }
-
- /**
- * Sets timeout.
- *
- * @param timeout the timeout
- */
- public void setTimeout(int timeout) {
- this.timeout = timeout;
- }
-
- /**
- * Gets begin time.
- *
- * @return the begin time
- */
- public long getBeginTime() {
- return beginTime;
- }
-
- /**
- * Sets begin time.
- *
- * @param beginTime the begin time
- */
- public void setBeginTime(long beginTime) {
- this.beginTime = beginTime;
- }
-
- /**
- * Gets transaction id.
- *
- * @return the transaction id
- */
- public long getTransactionId() {
- return transactionId;
- }
-
- /**
- * Sets transaction id.
- *
- * @param transactionId the transaction id
- */
- public void setTransactionId(long transactionId) {
- this.transactionId = transactionId;
- }
-
- /**
- * Gets application data.
- *
- * @return the application data
- */
- public String getApplicationData() {
- return applicationData;
- }
-
- /**
- * Sets application data.
- *
- * @param applicationData the application data
- */
- public void setApplicationData(String applicationData) {
- this.applicationData = applicationData;
- }
-
- /**
- * Gets gmt create.
- *
- * @return the gmt create
- */
- public Date getGmtCreate() {
- return gmtCreate;
- }
-
- /**
- * Sets gmt create.
- *
- * @param gmtCreate the gmt create
- */
- public void setGmtCreate(Date gmtCreate) {
- this.gmtCreate = gmtCreate;
- }
-
- /**
- * Gets gmt modified.
- *
- * @return the gmt modified
- */
- public Date getGmtModified() {
- return gmtModified;
- }
-
- /**
- * Sets gmt modified.
- *
- * @param gmtModified the gmt modified
- */
- public void setGmtModified(Date gmtModified) {
- this.gmtModified = gmtModified;
- }
-
- @Override
- public String toString(){
- return StringUtils.toString(this);
- }
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/LockDO.java b/core/src/main/java/io/seata/core/store/LockDO.java
deleted file mode 100644
index 51b242de627..00000000000
--- a/core/src/main/java/io/seata/core/store/LockDO.java
+++ /dev/null
@@ -1,178 +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.store;
-
-import io.seata.common.util.StringUtils;
-
-/**
- * The type Lock do.
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-public class LockDO {
-
- private String xid;
-
- private Long transactionId;
-
- private Long branchId;
-
- private String resourceId;
-
- private String tableName;
-
- private String pk;
-
- private String rowKey;
-
- /**
- * Instantiates a new Lock do.
- */
- public LockDO() {
- }
-
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
- /**
- * Gets transaction id.
- *
- * @return the transaction id
- */
- public Long getTransactionId() {
- return transactionId;
- }
-
- /**
- * Sets transaction id.
- *
- * @param transactionId the transaction id
- */
- public void setTransactionId(Long transactionId) {
- this.transactionId = transactionId;
- }
-
- /**
- * Gets resource id.
- *
- * @return the resource id
- */
- public String getResourceId() {
- return resourceId;
- }
-
- /**
- * Sets resource id.
- *
- * @param resourceId the resource id
- */
- public void setResourceId(String resourceId) {
- this.resourceId = resourceId;
- }
-
- /**
- * Gets row key.
- *
- * @return the row key
- */
- public String getRowKey() {
- return rowKey;
- }
-
- /**
- * Sets row key.
- *
- * @param rowKey the row key
- */
- public void setRowKey(String rowKey) {
- this.rowKey = rowKey;
- }
-
- /**
- * Gets table name.
- *
- * @return the table name
- */
- public String getTableName() {
- return tableName;
- }
-
- /**
- * Sets table name.
- *
- * @param tableName the table name
- */
- public void setTableName(String tableName) {
- this.tableName = tableName;
- }
-
- /**
- * Gets pk.
- *
- * @return the pk
- */
- public String getPk() {
- return pk;
- }
-
- /**
- * Sets pk.
- *
- * @param pk the pk
- */
- public void setPk(String pk) {
- this.pk = pk;
- }
-
- /**
- * Gets branch id.
- *
- * @return the branch id
- */
- public Long getBranchId() {
- return branchId;
- }
-
- /**
- * Sets branch id.
- *
- * @param branchId the branch id
- */
- public void setBranchId(Long branchId) {
- this.branchId = branchId;
- }
-
- @Override
- public String toString() {
- return StringUtils.toString(this);
- }
-}
diff --git a/core/src/main/java/io/seata/core/store/LockStore.java b/core/src/main/java/io/seata/core/store/LockStore.java
deleted file mode 100644
index 49e92e6ab10..00000000000
--- a/core/src/main/java/io/seata/core/store/LockStore.java
+++ /dev/null
@@ -1,68 +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.store;
-
-import java.util.List;
-
-/**
- * The interface Lock store.
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-public interface LockStore {
-
- /**
- * Acquire lock boolean.
- *
- * @param lockDO the lock do
- * @return the boolean
- */
- boolean acquireLock(LockDO lockDO);
-
-
- /**
- * Acquire lock boolean.
- *
- * @param lockDOs the lock d os
- * @return the boolean
- */
- boolean acquireLock(List lockDOs);
-
- /**
- * Un lock boolean.
- *
- * @param lockDO the lock do
- * @return the boolean
- */
- boolean unLock(LockDO lockDO);
-
- /**
- * Un lock boolean.
- *
- * @param lockDOs the lock d os
- * @return the boolean
- */
- boolean unLock(List lockDOs);
-
- /**
- * Is lockable boolean.
- *
- * @param lockDOs the lock do
- * @return the boolean
- */
- boolean isLockable(List lockDOs);
-}
diff --git a/core/src/main/java/io/seata/core/store/LogStore.java b/core/src/main/java/io/seata/core/store/LogStore.java
deleted file mode 100644
index f02b0ddc6d2..00000000000
--- a/core/src/main/java/io/seata/core/store/LogStore.java
+++ /dev/null
@@ -1,110 +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.store;
-
-
-import java.util.List;
-
-/**
- * the transaction log store
- *
- * @author zhangsen
- * @data 2019 /3/26
- */
-public interface LogStore {
-
- /**
- * Query global transaction do global transaction do.
- *
- * @param xid the xid
- * @return the global transaction do
- */
- GlobalTransactionDO queryGlobalTransactionDO(String xid);
-
- /**
- * Query global transaction do global transaction do.
- *
- * @param transactionId the transaction id
- * @return the global transaction do
- */
- GlobalTransactionDO queryGlobalTransactionDO(long transactionId);
-
- /**
- * Query global transaction do list.
- *
- * @param status the status
- * @param limit the limit
- * @return the list
- */
- List queryGlobalTransactionDO(int[] status, int limit);
-
- /**
- * Insert global transaction do boolean.
- *
- * @param globalTransactionDO the global transaction do
- * @return the boolean
- */
- boolean insertGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
-
- /**
- * Update global transaction do boolean.
- *
- * @param globalTransactionDO the global transaction do
- * @return the boolean
- */
- boolean updateGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
-
- /**
- * Delete global transaction do boolean.
- *
- * @param globalTransactionDO the global transaction do
- * @return the boolean
- */
- boolean deleteGlobalTransactionDO(GlobalTransactionDO globalTransactionDO);
-
- /**
- * Query branch transaction do boolean.
- *
- * @param xid the xid
- * @return the boolean
- */
- List queryBranchTransactionDO(String xid);
-
- /**
- * Insert branch transaction do boolean.
- *
- * @param branchTransactionDO the branch transaction do
- * @return the boolean
- */
- boolean insertBranchTransactionDO(BranchTransactionDO branchTransactionDO);
-
- /**
- * Update branch transaction do boolean.
- *
- * @param branchTransactionDO the branch transaction do
- * @return the boolean
- */
- boolean updateBranchTransactionDO(BranchTransactionDO branchTransactionDO);
-
- /**
- * Delete branch transaction do boolean.
- *
- * @param branchTransactionDO the branch transaction do
- * @return the boolean
- */
- boolean deleteBranchTransactionDO(BranchTransactionDO branchTransactionDO);
-
-}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java b/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java
deleted file mode 100644
index 2cdbcb00ce6..00000000000
--- a/core/src/main/java/io/seata/core/store/db/AbstractDataSourceGenerator.java
+++ /dev/null
@@ -1,148 +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.store.db;
-
-import io.seata.common.exception.StoreException;
-import io.seata.common.util.StringUtils;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
-import io.seata.core.constants.DBType;
-
-/**
- * The type Abstract data source generator.
- *
- * @author zhangsen
- * @data 2019 /4/24
- */
-public abstract class AbstractDataSourceGenerator implements DataSourceGenerator {
-
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
- /**
- * Get db type db type.
- *
- * @return the db type
- */
- protected DBType getDBType(){
- return DBType.valueof(CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE));
- }
-
- /**
- * Get url string.
- *
- * @return the string
- */
- protected String getUrl(){
- String url = CONFIG.getConfig(ConfigurationKeys.STORE_DB_URL);
- if(StringUtils.isBlank(url)){
- throw new StoreException("the {store.db.url} can't empty.");
- }
- return url;
- }
-
- /**
- * Get user string.
- *
- * @return the string
- */
- protected String getUser(){
- String user = CONFIG.getConfig(ConfigurationKeys.STORE_DB_USER);
- if(StringUtils.isBlank(user)){
- throw new StoreException("the {store.db.user} can't empty.");
- }
- return user;
- }
-
- /**
- * Get password string.
- *
- * @return the string
- */
- protected String getPassword(){
- String password = CONFIG.getConfig(ConfigurationKeys.STORE_DB_PASSWORD);
- return password;
- }
-
- /**
- * Get min conn int.
- *
- * @return the int
- */
- protected int getMinConn(){
- int minConn = CONFIG.getInt(ConfigurationKeys.STORE_DB_MIN_CONN);
- return minConn<0?0:minConn;
- }
-
- /**
- * Get max conn int.
- *
- * @return the int
- */
- protected int getMaxConn(){
- int maxConn = CONFIG.getInt(ConfigurationKeys.STORE_DB_MAX_CONN);
- return maxConn<0?1:maxConn;
- }
-
-
- /**
- * Get driver name string.
- *
- * @param dbType the db type
- * @return the string
- */
- protected static String getDriverName(DBType dbType){
- if(DBType.H2.equals(dbType)){
- return "org.h2.Driver";
- }else if(DBType.MYSQL.equals(dbType)){
- return "com.mysql.jdbc.Driver";
- }else if(DBType.ORACLE.equals(dbType)){
- return "oracle.jdbc.OracleDriver";
- }else if(DBType.SYBAEE.equals(dbType)){
- return "com.sybase.jdbc2.jdbc.SybDriver";
- }else if(DBType.SQLSERVER.equals(dbType)){
- return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
- }else if(DBType.SQLITE.equals(dbType)){
- return "org.sqlite.JDBC";
- }else if(DBType.POSTGRESQL.equals(dbType)){
- return "org.postgresql.Driver";
- }else if(DBType.ACCESS.equals(dbType)){
- return "com.hxtt.sql.access.AccessDriver";
- }else if(DBType.DB2.equals(dbType)){
- return "com.ibm.db2.jcc.DB2Driver";
- }else {
- throw new StoreException("Unsupported database type, dbType:" + dbType);
- }
- }
-
- /**
- * Get validation query string.
- *
- * @param dbType the db type
- * @return the string
- */
- protected String getValidationQuery(DBType dbType){
- if(DBType.ORACLE.equals(dbType)){
- return "select sysdate from dual";
- }else {
- return "select 1";
- }
- }
-
-}
diff --git a/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java b/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java
deleted file mode 100644
index 5687513969b..00000000000
--- a/core/src/main/java/io/seata/core/store/db/DataSourceGenerator.java
+++ /dev/null
@@ -1,35 +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.store.db;
-
-import javax.sql.DataSource;
-
-/**
- * The interface Data source generator.
- *
- * @author zhangsen
- * @data 2019 /4/24
- */
-public interface DataSourceGenerator {
-
- /**
- * create DataSource from config
- *
- * @return data source
- */
- DataSource generateDataSource();
-
-}
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
deleted file mode 100644
index b1aac288814..00000000000
--- a/core/src/main/java/io/seata/core/store/db/LockStoreDataBaseDAO.java
+++ /dev/null
@@ -1,356 +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.store.db;
-
-import io.seata.common.exception.StoreException;
-import io.seata.common.executor.Initialize;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.StringUtils;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationFactory;
-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.ArrayList;
-import java.util.List;
-
-/**
- * The type Data base lock store.
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-@LoadLevel(name = "db")
-public class LockStoreDataBaseDAO implements LockStore, Initialize {
-
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
- /**
- * The Log store data source.
- */
- protected DataSource logStoreDataSource = null;
-
- /**
- * The Lock table.
- */
- protected String lockTable;
-
- /**
- * The Db type.
- */
- protected String dbType;
-
- /**
- * Instantiates a new Data base lock store dao.
- *
- * @param logStoreDataSource the log store data source
- */
- public LockStoreDataBaseDAO(DataSource logStoreDataSource) {
- this.logStoreDataSource = logStoreDataSource;
- }
-
- @Override
- public void init() {
- lockTable = CONFIG.getConfig(ConfigurationKeys.LOCK_DB_TABLE, ConfigurationKeys.LOCK_DB_DEFAULT_TABLE);
- dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
- if (StringUtils.isBlank(dbType)) {
- throw new StoreException("there must be db type.");
- }
- if (logStoreDataSource == null) {
- throw new StoreException("there must be logStoreDataSource.");
- }
- }
-
- @Override
- public boolean acquireLock(LockDO lockDO) {
- List locks = new ArrayList<>();
- locks.add(lockDO);
- return acquireLock(locks);
- }
-
- @Override
- public boolean acquireLock(List lockDOs) {
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(false);
-
- //check lock
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i < lockDOs.size(); i++){
- sb.append("?");
- if( i != (lockDOs.size() - 1)){
- sb.append(", ");
- }
- }
- boolean canLock = true, isReLock = false;
- //query
- String checkLockSQL = LockStoreSqls.getCheckLockableSql(lockTable, sb.toString(), dbType);
- ps = conn.prepareStatement(checkLockSQL);
- for (int i = 0; i < lockDOs.size(); i++){
- ps.setString(i+1, lockDOs.get(i).getRowKey());
- }
- rs = ps.executeQuery();
- while (rs.next()) {
- if(StringUtils.equals(rs.getString("xid"), lockDOs.get(0).getXid())){
- isReLock = true;
- }else {
- canLock &= false;
- }
- }
-
- if(!canLock){
- conn.rollback();
- return false;
- }
-
- if(isReLock){
- conn.rollback();
- return true;
- }
-
- //lock
- for(LockDO lockDO : lockDOs){
- if(!doAcquireLock(conn, lockDO)) {
- conn.rollback();
- return false;
- }
- }
- conn.commit();
- return true;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if (ps != null) {
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean unLock(LockDO lockDO) {
- List locks = new ArrayList<>();
- locks.add(lockDO);
- return unLock(locks);
- }
-
- @Override
- public boolean unLock(List lockDOs) {
- Connection conn = null;
- PreparedStatement ps = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
-
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i< lockDOs.size(); i++){
- sb.append("?");
- if(i != (lockDOs.size() - 1)){
- sb.append(", ");
- }
- }
- //batch release lock
- String batchDeleteSQL = LockStoreSqls.getBatchDeleteLockSql(lockTable, sb.toString(), dbType);
- ps = conn.prepareStatement(batchDeleteSQL);
- ps.setString(1, lockDOs.get(0).getXid());
- for(int i = 0; i< lockDOs.size(); i++){
- ps.setString(i+2, lockDOs.get(i).getRowKey());
- }
- return ps.executeUpdate() > 0;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean isLockable(List lockDOs) {
- Connection conn = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- if(!checkLockable(conn, lockDOs)){
- return false;
- }
- return true;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- /**
- * Do acquire lock boolean.
- *
- * @param conn the conn
- * @param lockDO the lock do
- * @return the boolean
- */
- protected boolean doAcquireLock(Connection conn, LockDO lockDO) {
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- //insert
- String insertLockSQL = LockStoreSqls.getInsertLockSQL(lockTable, dbType);
- ps = conn.prepareStatement(insertLockSQL);
- ps.setString(1, lockDO.getXid());
- ps.setLong(2, lockDO.getTransactionId());
- ps.setLong(3, lockDO.getBranchId());
- ps.setString(4, lockDO.getResourceId());
- ps.setString(5, lockDO.getTableName());
- ps.setString(6, lockDO.getPk());
- ps.setString(7, lockDO.getRowKey());
- return ps.executeUpdate() > 0;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if (ps != null) {
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- /**
- * Check lock boolean.
- *
- * @param conn the conn
- * @param lockDOs the lock do
- * @return the boolean
- */
- protected boolean checkLockable(Connection conn, List lockDOs){
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i < lockDOs.size(); i++){
- sb.append("?");
- if( i != (lockDOs.size() - 1)){
- sb.append(", ");
- }
- }
-
- //query
- String checkLockSQL = LockStoreSqls.getCheckLockableSql(lockTable, sb.toString(), dbType);
- ps = conn.prepareStatement(checkLockSQL);
- for (int i = 0; i < lockDOs.size(); i++){
- ps.setString(i+1, lockDOs.get(i).getRowKey());
- }
- rs = ps.executeQuery();
- while (rs.next()) {
- String xid = rs.getString("xid");
- if(!StringUtils.equals(xid, lockDOs.get(0).getXid())){
- return false;
- }
- }
- return true;
- }catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (rs != null) {
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if (ps != null) {
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- /**
- * Sets lock table.
- *
- * @param lockTable the lock table
- */
- public void setLockTable(String lockTable) {
- this.lockTable = lockTable;
- }
-
- /**
- * Sets db type.
- *
- * @param dbType the db type
- */
- public void setDbType(String dbType) {
- this.dbType = dbType;
- }
-
- /**
- * Sets log store data source.
- *
- * @param logStoreDataSource the log store data source
- */
- public void setLogStoreDataSource(DataSource logStoreDataSource) {
- this.logStoreDataSource = logStoreDataSource;
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/LockStoreSqls.java b/core/src/main/java/io/seata/core/store/db/LockStoreSqls.java
deleted file mode 100644
index 7c95473e269..00000000000
--- a/core/src/main/java/io/seata/core/store/db/LockStoreSqls.java
+++ /dev/null
@@ -1,143 +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.store.db;
-
-import io.seata.common.exception.NotSupportYetException;
-import io.seata.core.constants.DBType;
-
-/**
- * The type Lock store sqls.
- *
- * @author zhangsen
- * @data 2019 /4/26
- */
-public class LockStoreSqls {
-
- /**
- * The constant LOCK_TABLE_PLACEHOLD.
- */
- public static final String LOCK_TABLE_PLACEHOLD = " #lock_table# ";
-
- /**
- * The constant IN_PARAMS_PLACEHOLD.
- */
- public static final String IN_PARAMS_PLACEHOLD = " #in_params# ";
-
- /**
- * The constant ALL_COLUMNS.
- */
- public static final String ALL_COLUMNS = "xid, transaction_id, branch_id, resource_id, table_name, pk, row_key, gmt_create, gmt_modified";
-
- /**
- * The constant INSERT_LOCK_SQL_MYSQL.
- */
- public static final String INSERT_LOCK_SQL_MYSQL = "insert into " + LOCK_TABLE_PLACEHOLD + "("+ ALL_COLUMNS +")" +
- "values (?, ?, ?, ?, ?, ?, ?, now(), now())";
-
- /**
- * The constant INSERT_LOCK_SQL_ORACLE.
- */
- public static final String INSERT_LOCK_SQL_ORACLE = "insert into " + LOCK_TABLE_PLACEHOLD + "("+ ALL_COLUMNS +")" +
- "values (?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)";
-
- /**
- * The constant DELETE_LOCK_SQL.
- */
- public static final String DELETE_LOCK_SQL = "delete from " + LOCK_TABLE_PLACEHOLD + " where row_key = ? and xid = ?";
-
- /**
- * The constant BATCH_DELETE_LOCK_SQL.
- */
- public static final String BATCH_DELETE_LOCK_SQL = "delete from " + LOCK_TABLE_PLACEHOLD + " where xid = ? and row_key in ("+ IN_PARAMS_PLACEHOLD +") ";
-
- /**
- * The constant QUERY_LOCK_SQL.
- */
- public static final String QUERY_LOCK_SQL = "select " + ALL_COLUMNS + " from " + LOCK_TABLE_PLACEHOLD
- + " where row_key = ? ";
-
- /**
- * The constant CHECK_LOCK_SQL.
- */
- public static final String CHECK_LOCK_SQL = "select " + ALL_COLUMNS + " from " + LOCK_TABLE_PLACEHOLD
- + " where row_key in ("+ IN_PARAMS_PLACEHOLD +")" ;
-
- /**
- * Get insert lock sql string.
- *
- * @param lockTable the lock table
- * @param dbType the db type
- * @return the string
- */
- public static String getInsertLockSQL(String lockTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return INSERT_LOCK_SQL_MYSQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return INSERT_LOCK_SQL_ORACLE.replace(LOCK_TABLE_PLACEHOLD, lockTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get delete lock sql string.
- *
- * @param lockTable the lock table
- * @param dbType the db type
- * @return the string
- */
- public static String getDeleteLockSql(String lockTable, String dbType){
- return DELETE_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
- }
-
- /**
- * Get batch delete lock sql string.
- *
- * @param lockTable the lock table
- * @param paramPlaceHold the param place hold
- * @param dbType the db type
- * @return the string
- */
- public static String getBatchDeleteLockSql(String lockTable, String paramPlaceHold, String dbType){
- return BATCH_DELETE_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable).replace(IN_PARAMS_PLACEHOLD, paramPlaceHold);
- }
-
- /**
- * Get query lock sql string.
- *
- * @param lockTable the lock table
- * @param dbType the db type
- * @return the string
- */
- public static String getQueryLockSql(String lockTable, String dbType){
- return QUERY_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable);
- }
-
- /**
- * Get check lock sql string.
- *
- * @param lockTable the lock table
- * @param paramPlaceHold the param place hold
- * @param dbType the db type
- * @return the string
- */
- public static String getCheckLockableSql(String lockTable, String paramPlaceHold, String dbType){
- return CHECK_LOCK_SQL.replace(LOCK_TABLE_PLACEHOLD, lockTable).replace(IN_PARAMS_PLACEHOLD, paramPlaceHold);
- }
-
-}
diff --git a/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java b/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java
deleted file mode 100644
index 4248ce45929..00000000000
--- a/core/src/main/java/io/seata/core/store/db/LogStoreDataBaseDAO.java
+++ /dev/null
@@ -1,533 +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.store.db;
-
-import io.seata.common.exception.StoreException;
-import io.seata.common.executor.Initialize;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.StringUtils;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
-import io.seata.core.store.BranchTransactionDO;
-import io.seata.core.store.GlobalTransactionDO;
-import io.seata.core.store.LogStore;
-
-import javax.sql.DataSource;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The type Log store data base dao.
- *
- * @author zhangsen
- * @data 2019 /4/2
- */
-@LoadLevel(name = "db")
-public class LogStoreDataBaseDAO implements LogStore, Initialize {
-
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
- /**
- * The Log store data source.
- */
- protected DataSource logStoreDataSource = null;
-
- /**
- * The Global table.
- */
- protected String globalTable;
-
- /**
- * The Brach table.
- */
- protected String brachTable;
-
- private String dbType;
-
- /**
- * Instantiates a new Log store data base dao.
- */
- public LogStoreDataBaseDAO(){
- }
-
- /**
- * Instantiates a new Log store data base dao.
- *
- * @param logStoreDataSource the log store data source
- */
- public LogStoreDataBaseDAO(DataSource logStoreDataSource) {
- this.logStoreDataSource = logStoreDataSource;
- }
-
- @Override
- public void init() {
- globalTable = CONFIG.getConfig(ConfigurationKeys.STORE_DB_GLOBAL_TABLE, ConfigurationKeys.STORE_DB_GLOBAL_DEFAULT_TABLE);
- brachTable = CONFIG.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, ConfigurationKeys.STORE_DB_BRANCH_DEFAULT_TABLE);
- dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
- if(StringUtils.isBlank(dbType)){
- throw new StoreException("there must be db type.");
- }
- if(logStoreDataSource == null){
- throw new StoreException("there must be logStoreDataSource.");
- }
- }
-
- @Override
- public GlobalTransactionDO queryGlobalTransactionDO(String xid) {
- String sql = LogStoreSqls.getQueryGlobalTransactionSQL(globalTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setString(1, xid);
- rs = ps.executeQuery();
- if(rs.next()){
- return convertGlobalTransactionDO(rs);
- }else {
- return null;
- }
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(rs != null){
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
-
- @Override
- public GlobalTransactionDO queryGlobalTransactionDO(long transactionId){
- String sql = LogStoreSqls.getQueryGlobalTransactionSQLByTransactionId(globalTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setLong(1, transactionId);
- rs = ps.executeQuery();
- if(rs.next()){
- return convertGlobalTransactionDO(rs);
- }else {
- return null;
- }
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(rs != null){
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public List queryGlobalTransactionDO(int[] statuses, int limit) {
- List ret = new ArrayList();
- Connection conn = null;
- PreparedStatement ps = null;
- ResultSet rs = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
-
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i < statuses.length; i ++){
- sb.append("?");
- if(i != (statuses.length -1)){
- sb.append(", ");
- }
- }
-
- String sql = LogStoreSqls.getQueryGlobalTransactionSQLByStatus(globalTable, dbType, sb.toString());
- ps = conn.prepareStatement(sql);
- for(int i = 0; i < statuses.length; i ++){
- int status = statuses[i];
- ps.setInt(i+1, status);
- }
- ps.setInt(statuses.length +1, limit);
- rs = ps.executeQuery();
- while(rs.next()){
- ret.add(convertGlobalTransactionDO(rs));
- }
- return ret;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(rs != null){
- try {
- rs.close();
- } catch (SQLException e) {
- }
- }
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean insertGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
- String sql = LogStoreSqls.getInsertGlobalTransactionSQL(globalTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try{
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setString(1, globalTransactionDO.getXid());
- ps.setLong(2, globalTransactionDO.getTransactionId());
- ps.setInt(3, globalTransactionDO.getStatus());
- ps.setString(4, globalTransactionDO.getApplicationId());
- ps.setString(5, globalTransactionDO.getTransactionServiceGroup());
- ps.setString(6, globalTransactionDO.getTransactionName());
- ps.setInt(7, globalTransactionDO.getTimeout());
- ps.setLong(8, globalTransactionDO.getBeginTime());
- ps.setString(9, globalTransactionDO.getApplicationData());
- return ps.executeUpdate() > 0;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean updateGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
- String sql = LogStoreSqls.getUpdateGlobalTransactionStatusSQL(globalTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try{
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setInt(1, globalTransactionDO.getStatus());
- ps.setString(2, globalTransactionDO.getXid());
- return ps.executeUpdate() > 0;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean deleteGlobalTransactionDO(GlobalTransactionDO globalTransactionDO) {
- String sql = LogStoreSqls.getDeleteGlobalTransactionSQL(globalTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try{
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setString(1, globalTransactionDO.getXid());
- return ps.executeUpdate() > 0;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public List queryBranchTransactionDO(String xid) {
- List rets = new ArrayList<>();
- String sql = LogStoreSqls.getQureyBranchTransaction(brachTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
-
- ps = conn.prepareStatement(sql);
- ps.setString(1, xid);
-
- ResultSet rs = ps.executeQuery();
- while(rs.next()){
- rets.add(convertBranchTransactionDO(rs));
- }
- return rets;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (ps != null) {
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean insertBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
- String sql = LogStoreSqls.getInsertBranchTransactionSQL(brachTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try {
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setString(1, branchTransactionDO.getXid());
- ps.setLong(2, branchTransactionDO.getTransactionId());
- ps.setLong(3, branchTransactionDO.getBranchId());
- ps.setString(4, branchTransactionDO.getResourceGroupId());
- ps.setString(5, branchTransactionDO.getResourceId());
- ps.setString(6, branchTransactionDO.getLockKey());
- ps.setString(7, branchTransactionDO.getBranchType());
- ps.setInt(8, branchTransactionDO.getStatus());
- ps.setString(9, branchTransactionDO.getClientId());
- ps.setString(10, branchTransactionDO.getApplicationData());
- return ps.executeUpdate() > 0;
- } catch (SQLException e) {
- throw new StoreException(e);
- } finally {
- if (ps != null) {
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean updateBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
- String sql = LogStoreSqls.getUpdateBranchTransactionStatusSQL(brachTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try{
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setInt(1, branchTransactionDO.getStatus());
- ps.setString(2, branchTransactionDO.getXid());
- ps.setLong(3, branchTransactionDO.getBranchId());
- return ps.executeUpdate() > 0;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- @Override
- public boolean deleteBranchTransactionDO(BranchTransactionDO branchTransactionDO) {
- String sql = LogStoreSqls.getDeleteBranchTransactionByBranchIdSQL(brachTable, dbType);
- Connection conn = null;
- PreparedStatement ps = null;
- try{
- conn = logStoreDataSource.getConnection();
- conn.setAutoCommit(true);
- ps = conn.prepareStatement(sql);
- ps.setString(1, branchTransactionDO.getXid());
- ps.setLong(2, branchTransactionDO.getBranchId());
- return ps.executeUpdate() > 0;
- }catch (SQLException e){
- throw new StoreException(e);
- }finally {
- if(ps != null){
- try {
- ps.close();
- } catch (SQLException e) {
- }
- }
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
-
- private GlobalTransactionDO convertGlobalTransactionDO(ResultSet rs) throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid(rs.getString("xid"));
- globalTransactionDO.setStatus(rs.getInt("status"));
- globalTransactionDO.setApplicationId(rs.getString("application_id"));
- globalTransactionDO.setBeginTime(rs.getLong("begin_time"));
- globalTransactionDO.setTimeout(rs.getInt("timeout"));
- globalTransactionDO.setTransactionId(rs.getLong("transaction_id"));
- globalTransactionDO.setTransactionName(rs.getString("transaction_name"));
- globalTransactionDO.setTransactionServiceGroup(rs.getString("transaction_service_group"));
- globalTransactionDO.setApplicationData(rs.getString("application_data"));
- globalTransactionDO.setGmtCreate(rs.getTimestamp("gmt_create"));
- globalTransactionDO.setGmtModified(rs.getTimestamp("gmt_modified"));
- return globalTransactionDO;
- }
-
- private BranchTransactionDO convertBranchTransactionDO(ResultSet rs) throws SQLException {
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceGroupId(rs.getString("resource_group_id"));
- branchTransactionDO.setStatus(rs.getInt("status"));
- branchTransactionDO.setApplicationData(rs.getString("application_data"));
- branchTransactionDO.setClientId(rs.getString("client_id"));
- branchTransactionDO.setLockKey(rs.getString("lock_key"));
- branchTransactionDO.setXid(rs.getString("xid"));
- branchTransactionDO.setResourceId(rs.getString("resource_id"));
- branchTransactionDO.setBranchId(rs.getLong("branch_id"));
- branchTransactionDO.setBranchType(rs.getString("branch_type"));
- branchTransactionDO.setTransactionId(rs.getLong("transaction_id"));
- branchTransactionDO.setGmtCreate(rs.getTimestamp("gmt_create"));
- branchTransactionDO.setGmtModified(rs.getTimestamp("gmt_modified"));
- return branchTransactionDO;
- }
-
- /**
- * Sets log store data source.
- *
- * @param logStoreDataSource the log store data source
- */
- public void setLogStoreDataSource(DataSource logStoreDataSource) {
- this.logStoreDataSource = logStoreDataSource;
- }
-
- /**
- * Sets global table.
- *
- * @param globalTable the global table
- */
- public void setGlobalTable(String globalTable) {
- this.globalTable = globalTable;
- }
-
- /**
- * Sets brach table.
- *
- * @param brachTable the brach table
- */
- public void setBrachTable(String brachTable) {
- this.brachTable = brachTable;
- }
-
- /**
- * Sets db type.
- *
- * @param dbType the db type
- */
- public void setDbType(String dbType) {
- this.dbType = dbType;
- }
-}
\ No newline at end of file
diff --git a/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java b/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java
deleted file mode 100644
index 69308324d63..00000000000
--- a/core/src/main/java/io/seata/core/store/db/LogStoreSqls.java
+++ /dev/null
@@ -1,323 +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.store.db;
-
-
-import io.seata.common.exception.NotSupportYetException;
-import io.seata.core.constants.DBType;
-
-/**
- * database log store SQLs
- *
- * @author zhangsen
- * @data 2019 /4/2
- */
-public class LogStoreSqls {
-
- /**
- * The constant GLOBAL_TABLE_PLACEHOLD.
- */
- public static final String GLOBAL_TABLE_PLACEHOLD = " #global_table# ";
-
- /**
- * The constant BRANCH_TABLE_PLACEHOLD.
- */
- public static final String BRANCH_TABLE_PLACEHOLD = " #branch_table# ";
-
-
- /**
- * The constant PRAMETER_PLACEHOLD.
- */
- public static final String PRAMETER_PLACEHOLD = " #PRAMETER_PLACEHOLD# ";
-
- /**
- * The constant ALL_GLOBAL_COLUMNS.
- */
- public static final String ALL_GLOBAL_COLUMNS = "xid, transaction_id, status, application_id, transaction_service_group, transaction_name, timeout, begin_time, application_data, gmt_create, gmt_modified ";
-
- /**
- * The constant ALL_BRANCH_COLUMNS.
- */
- protected static final String ALL_BRANCH_COLUMNS = "xid, transaction_id, branch_id, resource_group_id, resource_id, lock_key, branch_type, status, client_id, application_data, gmt_create, gmt_modified ";
-
- /**
- * The constant INSERT_GLOBAL_TRANSACTION_MYSQL.
- */
- public static final String INSERT_GLOBAL_TRANSACTION_MYSQL = "insert into " + GLOBAL_TABLE_PLACEHOLD + "("+ ALL_GLOBAL_COLUMNS +")" +
- "values(?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now()) ";
-
- /**
- * The constant INSERT_GLOBAL_TRANSACTION_ORACLE.
- */
- public static final String INSERT_GLOBAL_TRANSACTION_ORACLE = "insert into " + GLOBAL_TABLE_PLACEHOLD + "("+ ALL_GLOBAL_COLUMNS +")" +
- "values(?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate) ";
-
- /**
- * The constant UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL.
- */
- public static final String UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL = "update "+ GLOBAL_TABLE_PLACEHOLD + " set status = ?, gmt_modified = now() where xid = ?";
-
- /**
- * The constant UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE.
- */
- public static final String UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE = "update "+ GLOBAL_TABLE_PLACEHOLD + " set status = ?, gmt_modified = sysdate where xid = ?";
-
- /**
- * The constant DELETE_GLOBAL_TRANSACTION.
- */
- public static final String DELETE_GLOBAL_TRANSACTION = "delete from " + GLOBAL_TABLE_PLACEHOLD + " where xid = ?";
-
- /**
- * The constant QUERY_GLOBAL_TRANSACTION.
- */
- public static final String QUERY_GLOBAL_TRANSACTION = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where xid = ?";
-
-
- /**
- * The constant QUERY_GLOBAL_TRANSACTION_ID.
- */
- public static final String QUERY_GLOBAL_TRANSACTION_BY_ID = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where transaction_id = ?";
-
-
- /**
- * The constant QUERY_GLOBAL_TRANSACTION_BY_STATUS.
- */
- public static final String QUERY_GLOBAL_TRANSACTION_BY_STATUS = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD +
- " where status in (" + PRAMETER_PLACEHOLD + ") order by gmt_modified limit ?";
- /**
- * The constant QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL.
- */
- public static final String QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL = "select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where status in (" +
- "0, 2, 3, 4, 5, 6, 7, 8, 10 ,12, 14) order by gmt_modified limit ?";
-
- /**
- * The constant QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE.
- */
- public static final String QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE = "select A.* from ( select "+ALL_GLOBAL_COLUMNS+" from " + GLOBAL_TABLE_PLACEHOLD + " where status in (" +
- "0, 2, 3, 4, 5, 6, 7, 8, 10 ,12, 14) order by gmt_modified ) A where ROWNUM <= ?" ;
-
-
- /**
- * The constant INSERT_BRANCH_TRANSACTION_MYSQL.
- */
- public static final String INSERT_BRANCH_TRANSACTION_MYSQL = "insert into " + BRANCH_TABLE_PLACEHOLD + "("+ ALL_BRANCH_COLUMNS +")" +
- "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, now(), now())";
-
- /**
- * The constant INSERT_BRANCH_TRANSACTION_ORACLE.
- */
- public static final String INSERT_BRANCH_TRANSACTION_ORACLE = "insert into " + BRANCH_TABLE_PLACEHOLD + "("+ ALL_BRANCH_COLUMNS +")" +
- "values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)";
-
- /**
- * The constant UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL.
- */
- public static final String UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL = "update "+ BRANCH_TABLE_PLACEHOLD + " set status = ?, gmt_modified = now() where xid = ? and branch_id = ?";
-
- /**
- * The constant UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE.
- */
- public static final String UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE = "update "+ BRANCH_TABLE_PLACEHOLD + " set status = ?, gmt_modified = sysdate where xid = ? and branch_id = ?" ;
-
- /**
- * The constant DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID.
- */
- public static final String DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID = "delete from " + BRANCH_TABLE_PLACEHOLD + " where xid = ? and branch_id = ?";
-
- /**
- * The constant DELETE_BRANCH_TRANSACTION_BY_XID.
- */
- public static final String DELETE_BRANCH_TRANSACTION_BY_XID = "delete from " + BRANCH_TABLE_PLACEHOLD + " where xid = ?";
-
- /**
- * The constant QUREY_BRANCH_TRANSACTION.
- */
- public static final String QUREY_BRANCH_TRANSACTION = "select "+ALL_BRANCH_COLUMNS+" from " + BRANCH_TABLE_PLACEHOLD + " where xid = ?";
-
- /**
- * Get insert global transaction sql string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getInsertGlobalTransactionSQL(String globalTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return INSERT_GLOBAL_TRANSACTION_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return INSERT_GLOBAL_TRANSACTION_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get update global transaction status sql string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getUpdateGlobalTransactionStatusSQL(String globalTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return UPDATE_GLOBAL_TRANSACTION_STATUS_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return UPDATE_GLOBAL_TRANSACTION_STATUS_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get delete global transaction sql string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getDeleteGlobalTransactionSQL(String globalTable, String dbType){
- return DELETE_GLOBAL_TRANSACTION.replace(GLOBAL_TABLE_PLACEHOLD, globalTable );
- }
-
- /**
- * Get query global transaction sql string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getQueryGlobalTransactionSQL(String globalTable, String dbType){
- return QUERY_GLOBAL_TRANSACTION.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }
-
- /**
- * Get query global transaction sql by transaction id string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getQueryGlobalTransactionSQLByTransactionId(String globalTable, String dbType){
- return QUERY_GLOBAL_TRANSACTION_BY_ID.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }
-
-
- /**
- * Get query global transaction sql by status string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @param paramsPlaceHolder the params place holder
- * @return the string
- */
- public static String getQueryGlobalTransactionSQLByStatus(String globalTable, String dbType, String paramsPlaceHolder){
- return QUERY_GLOBAL_TRANSACTION_BY_STATUS.replace(GLOBAL_TABLE_PLACEHOLD, globalTable).replace(PRAMETER_PLACEHOLD, paramsPlaceHolder);
- }
-
- /**
- * Get query global transaction for recovery sql string.
- *
- * @param globalTable the global table
- * @param dbType the db type
- * @return the string
- */
- public static String getQueryGlobalTransactionForRecoverySQL(String globalTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_MYSQL.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return QUERY_GLOBAL_TRANSACTION_FOR_RECOVERY_ORACLE.replace(GLOBAL_TABLE_PLACEHOLD, globalTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get insert branch transaction sql string.
- *
- * @param branchTable the branch table
- * @param dbType the db type
- * @return the string
- */
- public static String getInsertBranchTransactionSQL(String branchTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return INSERT_BRANCH_TRANSACTION_MYSQL.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return INSERT_BRANCH_TRANSACTION_ORACLE.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get update branch transaction status sql string.
- *
- * @param branchTable the branch table
- * @param dbType the db type
- * @return the string
- */
- public static String getUpdateBranchTransactionStatusSQL(String branchTable, String dbType){
- if(DBType.MYSQL.name().equalsIgnoreCase(dbType)
- || DBType.OCEANBASE.name().equalsIgnoreCase(dbType)
- || DBType.H2.name().equalsIgnoreCase(dbType)){
- return UPDATE_BRANCH_TRANSACTION_STATUS_MYSQL.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }else if(DBType.ORACLE.name().equalsIgnoreCase(dbType)){
- return UPDATE_BRANCH_TRANSACTION_STATUS_ORACLE.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }else{
- throw new NotSupportYetException("unknown dbType:" + dbType);
- }
- }
-
- /**
- * Get delete branch transaction by branch id sql string.
- *
- * @param branchTable the branch table
- * @param dbType the db type
- * @return the string
- */
- public static String getDeleteBranchTransactionByBranchIdSQL(String branchTable, String dbType){
- return DELETE_BRANCH_TRANSACTION_BY_BRANCH_ID.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }
-
- /**
- * Get delete branch transaction by x id string.
- *
- * @param branchTable the branch table
- * @param dbType the db type
- * @return the string
- */
- public static String getDeleteBranchTransactionByXId(String branchTable, String dbType){
- return DELETE_BRANCH_TRANSACTION_BY_XID.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }
-
- /**
- * Get qurey branch transaction string.
- *
- * @param branchTable the branch table
- * @param dbType the db type
- * @return the string
- */
- public static String getQureyBranchTransaction(String branchTable, String dbType){
- return QUREY_BRANCH_TRANSACTION.replace(BRANCH_TABLE_PLACEHOLD, branchTable);
- }
-}
\ No newline at end of file
diff --git a/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore b/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore
deleted file mode 100644
index bd6ff3d994a..00000000000
--- a/core/src/main/resources/META-INF/services/io.seata.core.store.LockStore
+++ /dev/null
@@ -1 +0,0 @@
-io.seata.core.store.db.LockStoreDataBaseDAO
\ No newline at end of file
diff --git a/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore b/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore
deleted file mode 100644
index f95309566f9..00000000000
--- a/core/src/main/resources/META-INF/services/io.seata.core.store.LogStore
+++ /dev/null
@@ -1 +0,0 @@
-io.seata.core.store.db.LogStoreDataBaseDAO
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java b/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
deleted file mode 100644
index d76a6c79dc4..00000000000
--- a/core/src/test/java/io/seata/core/protocol/RegisterTMRequestTest.java
+++ /dev/null
@@ -1,192 +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.protocol;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-import io.netty.buffer.ByteBuf;
-import static io.netty.buffer.Unpooled.buffer;
-
-/**
- * RegisterTMRequest Test
- *
- * @author kaitithoma
- * @author Danaykap
- *
- * @date 2019/05/13
- *
- */
-
-public class RegisterTMRequestTest {
-
- 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);
-
- /** 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/store/db/DataBaseLockStoreDAOTest.java b/core/src/test/java/io/seata/core/store/db/DataBaseLockStoreDAOTest.java
deleted file mode 100644
index eee248eb8cd..00000000000
--- a/core/src/test/java/io/seata/core/store/db/DataBaseLockStoreDAOTest.java
+++ /dev/null
@@ -1,300 +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.store.db;
-
-import io.seata.core.store.LockDO;
-import org.apache.commons.dbcp.BasicDataSource;
-
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Assertions;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author zhangsen
- * @data 2019/4/26
- */
-public class DataBaseLockStoreDAOTest {
-
- static LockStoreDataBaseDAO dataBaseLockStoreDAO = null;
-
- static BasicDataSource dataSource = null;
-
- @BeforeAll
- public static void start(){
- dataSource = new BasicDataSource();
- dataSource.setDriverClassName("org.h2.Driver");
- dataSource.setUrl("jdbc:h2:./db_store/lock");
- dataSource.setUsername("sa");
- dataSource.setPassword("");
-
- dataBaseLockStoreDAO = new LockStoreDataBaseDAO(dataSource);
- dataBaseLockStoreDAO.setDbType("h2");
- dataBaseLockStoreDAO.setLockTable("lock_table");
-
- prepareTable(dataSource);
- }
-
- private static void prepareTable(BasicDataSource dataSource) {
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- Statement s = conn.createStatement();
- try {
- s.execute("drop table lock_table");
- } catch (Exception e) {
- }
- s.execute("CREATE TABLE lock_table ( xid varchar(96) , transaction_id long , branch_id long, resource_id varchar(32) ,table_name varchar(32) ,pk varchar(32) , row_key varchar(128) primary key not null, gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
- System.out.println("create table lock_table success.");
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- @Test
- public void test_acquireLocks() throws SQLException {
- List lockDOs = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-123:123");
- lock.setTransactionId(123L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs.add(lock);
- }
-
- boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
- Assertions.assertTrue(ret);
-
- String sql = "select * from lock_table where xid = 'abc-123:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
- } finally {
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
-
- Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
-
- }
-
-
- @Test
- public void test_re_acquireLocks() throws SQLException {
- List lockDOs = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-123:123");
- lock.setTransactionId(123L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs.add(lock);
- }
-
- boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
- Assertions.assertTrue(ret);
-
- String sql = "select * from lock_table where xid = 'abc-123:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
- } finally {
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
-
- //lock again
- Assertions.assertTrue(dataBaseLockStoreDAO.acquireLock(lockDOs));
-
- Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
-
- }
-
- @Test
- public void tes_unLocks() throws SQLException {
- List lockDOs = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-456:123");
- lock.setTransactionId(123L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs.add(lock);
- }
-
- boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
- Assertions.assertTrue(ret);
-
- String sql = "select * from lock_table where xid = 'abc-456:123' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
- rs.close();
-
- //unlock
- Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
-
- rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(false);
- }else {
- Assertions.assertTrue(true);
- }
-
- } finally {
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
-
-
- }
-
-
- @Test
- public void test_isLockable_can(){
- List lockDOs = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-678:123");
- lock.setTransactionId(123L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs.add(lock);
- }
-
- boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
- Assertions.assertTrue(ret);
-
- //unlock
- Assertions.assertTrue(dataBaseLockStoreDAO.unLock(lockDOs));
- }
-
- @Test
- public void test_isLockable_cannot() throws SQLException {
- List lockDOs = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-123:222");
- lock.setTransactionId(222L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs.add(lock);
- }
-
- boolean ret = dataBaseLockStoreDAO.acquireLock(lockDOs);
- Assertions.assertTrue(ret);
-
- String sql = "select * from lock_table where xid = 'abc-123:222' and table_name = 't' and row_key in ('abc-0','abc-1','abc-2')" ;
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
- } finally {
- if(conn != null){
- try {
- conn.close();
- } catch (SQLException e) {
- }
- }
- }
-
- List lockDOs_2 = new ArrayList<>();
- for(int i = 0; i < 3; i++){
- LockDO lock = new LockDO();
- lock.setResourceId("abc");
- lock.setXid("abc-123:333");
- lock.setTransactionId(333L);
- lock.setBranchId((long) i);
- lock.setRowKey("abc-"+i);
- lock.setPk(String.valueOf(i));
- lock.setTableName("t");
- lockDOs_2.add(lock);
- }
-
- boolean ret2 = dataBaseLockStoreDAO.acquireLock(lockDOs_2);
- Assertions.assertTrue(!ret2);
-
- }
-
-
-
-}
\ No newline at end of file
diff --git a/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java b/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java
deleted file mode 100644
index 12aaf5259ea..00000000000
--- a/core/src/test/java/io/seata/core/store/db/LogStoreDataBaseDAOTest.java
+++ /dev/null
@@ -1,659 +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.store.db;
-
-import io.seata.common.util.CollectionUtils;
-import io.seata.core.store.BranchTransactionDO;
-import io.seata.core.store.GlobalTransactionDO;
-import org.apache.commons.dbcp.BasicDataSource;
-
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Assertions;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.List;
-
-
-/**
- * @author zhangsen
- * @data 2019/4/26
- */
-public class LogStoreDataBaseDAOTest {
-
- static LogStoreDataBaseDAO logStoreDataBaseDAO = null;
-
- static BasicDataSource dataSource = null;
-
- @BeforeAll
- public static void start(){
- dataSource = new BasicDataSource();
- dataSource.setDriverClassName("org.h2.Driver");
- dataSource.setUrl("jdbc:h2:./db_store/log");
- dataSource.setUsername("sa");
- dataSource.setPassword("");
-
- logStoreDataBaseDAO = new LogStoreDataBaseDAO(dataSource);
- logStoreDataBaseDAO.setDbType("h2");
- logStoreDataBaseDAO.setGlobalTable("global_table");
- logStoreDataBaseDAO.setBrachTable("branch_table");
-
- prepareTable(dataSource);
- }
-
- private static void prepareTable(BasicDataSource dataSource) {
- Connection conn = null;
- try {
- conn = dataSource.getConnection();
- Statement s = conn.createStatement();
- try {
- s.execute("drop table global_table");
- } catch (Exception e) {
- }
-// xid, transaction_id, status, application_id, transaction_service_group, transaction_name, timeout, begin_time, application_data, gmt_create, gmt_modified
- s.execute("CREATE TABLE global_table ( xid varchar(96) primary key, transaction_id long , STATUS int, application_id varchar(32), transaction_service_group varchar(32) ,transaction_name varchar(32) ,timeout int, begin_time long, application_data varchar(500), gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
- System.out.println("create table global_table success.");
-
- try {
- s.execute("drop table branch_table");
- } catch (Exception e) {
- }
-// xid, transaction_id, branch_id, resource_group_id, resource_id, lock_key, branch_type, status, client_id, application_data, gmt_create, gmt_modified
- s.execute("CREATE TABLE branch_table ( xid varchar(96), transaction_id long , branch_id long primary key, resource_group_id varchar(32), resource_id varchar(32) ,lock_key varchar(64) ,branch_type varchar(32) , status int , client_id varchar(128), application_data varchar(500), gmt_create TIMESTAMP(6) ,gmt_modified TIMESTAMP(6) ) ");
- System.out.println("create table branch_table success.");
-
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (conn != null) {
- try {
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- @Test
- public void queryGlobalTransactionDO_by_xid() throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:978786");
- globalTransactionDO.setApplicationData("abc=87867978");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(143546567);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
-
-
- GlobalTransactionDO globalTransactionDO_db = logStoreDataBaseDAO.queryGlobalTransactionDO("abc-123:978786");
- Assertions.assertNotNull(globalTransactionDO_db);
-
- Assertions.assertEquals(globalTransactionDO_db.getBeginTime(), globalTransactionDO_db.getBeginTime());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionName(), globalTransactionDO_db.getTransactionName());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionId(), globalTransactionDO_db.getTransactionId());
- Assertions.assertEquals(globalTransactionDO_db.getStatus(), globalTransactionDO_db.getStatus());
- Assertions.assertEquals(globalTransactionDO_db.getTimeout(), globalTransactionDO_db.getTimeout());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionServiceGroup(), globalTransactionDO_db.getTransactionServiceGroup());
- Assertions.assertEquals(globalTransactionDO_db.getApplicationId(), globalTransactionDO_db.getApplicationId());
- Assertions.assertNotNull(globalTransactionDO_db.getGmtCreate());
- Assertions.assertNotNull(globalTransactionDO_db.getGmtModified());
-
-
- String delSql = "delete from global_table where xid= 'abc-123:978786'";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- //delete
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
-
- }
-
- @Test
- public void queryGlobalTransactionDO_by_transaction_id() throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:676787978");
- globalTransactionDO.setApplicationData("abc=234356");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(867978970);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
-
- GlobalTransactionDO globalTransactionDO_db = logStoreDataBaseDAO.queryGlobalTransactionDO(867978970L);
- Assertions.assertNotNull(globalTransactionDO_db);
-
- Assertions.assertEquals(globalTransactionDO_db.getXid(), globalTransactionDO_db.getXid());
- Assertions.assertEquals(globalTransactionDO_db.getBeginTime(), globalTransactionDO_db.getBeginTime());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionName(), globalTransactionDO_db.getTransactionName());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionId(), globalTransactionDO_db.getTransactionId());
- Assertions.assertEquals(globalTransactionDO_db.getStatus(), globalTransactionDO_db.getStatus());
- Assertions.assertEquals(globalTransactionDO_db.getTimeout(), globalTransactionDO_db.getTimeout());
- Assertions.assertEquals(globalTransactionDO_db.getTransactionServiceGroup(), globalTransactionDO_db.getTransactionServiceGroup());
- Assertions.assertEquals(globalTransactionDO_db.getApplicationId(), globalTransactionDO_db.getApplicationId());
- Assertions.assertNotNull(globalTransactionDO_db.getGmtCreate());
- Assertions.assertNotNull(globalTransactionDO_db.getGmtModified());
-
- String delSql = "delete from global_table where xid= 'abc-123:978786'";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- //delete
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
-
- }
-
- @Test
- public void queryGlobalTransactionDO_by_statuses() throws SQLException {
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:1267");
- globalTransactionDO.setApplicationData("abc=234356");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(867978970);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- Assertions.assertTrue(logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO));
- }
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:6978");
- globalTransactionDO.setApplicationData("abc=87867978");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(143546567);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(2);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
- }
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:5657");
- globalTransactionDO.setApplicationData("abc=5454");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(12345);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
- }
-
- List globalTransactionDOs = logStoreDataBaseDAO.queryGlobalTransactionDO(new int[]{1}, 10);
- Assertions.assertNotNull(globalTransactionDOs);
- Assertions.assertEquals(2, globalTransactionDOs.size());
-
- if("abc-123:5657".equals(globalTransactionDOs.get(0).getXid()) && "abc-123:1267".equals(globalTransactionDOs.get(1).getXid())){
- Assertions.assertTrue(true);
- }else if("abc-123:5657".equals(globalTransactionDOs.get(1).getXid()) && "abc-123:1267".equals(globalTransactionDOs.get(0).getXid())){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
-
- String delSql = "delete from global_table where xid in ('abc-123:1267', 'abc-123:6978', 'abc-123:5657')";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
- @Test
- public void queryGlobalTransactionDO_by_statuses_limit() throws SQLException {
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:1267");
- globalTransactionDO.setApplicationData("abc=234356");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(867978970);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- Assertions.assertTrue(logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO));
- }
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:6978");
- globalTransactionDO.setApplicationData("abc=87867978");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(143546567);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(2);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
- }
- {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:5657");
- globalTransactionDO.setApplicationData("abc=5454");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(12345);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
- }
-
- List globalTransactionDOs = logStoreDataBaseDAO.queryGlobalTransactionDO(new int[]{1}, 1);
- Assertions.assertNotNull(globalTransactionDOs);
- Assertions.assertEquals(1, globalTransactionDOs.size());
-
- if("abc-123:1267".equals(globalTransactionDOs.get(0).getXid())){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
-
- String delSql = "delete from global_table where xid in ('abc-123:1267', 'abc-123:6978', 'abc-123:5657')";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
-
- }
-
- @Test
- public void insertGlobalTransactionDO() throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:333");
- globalTransactionDO.setApplicationData("abc=5454");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(12345);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
-
- String sql = "select * from global_table where xid= 'abc-123:333'";
- String delSql = "delete from global_table where xid= 'abc-123:333'";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else{
- Assertions.assertTrue(false);
- }
-
- conn.createStatement().execute(delSql);
-
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
- @Test
- public void updateGlobalTransactionDO() throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:222");
- globalTransactionDO.setApplicationData("abc=5454");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(12345);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
-
- String sql = "select * from global_table where xid= 'abc-123:222'";
- String delSql = "delete from global_table where xid= 'abc-123:222'";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- Assertions.assertEquals(1, rs.getInt("status"));
- }else{
- Assertions.assertTrue(false);
- }
- rs.close();
-
- //update
- globalTransactionDO.setStatus(2);
- Assertions.assertTrue(logStoreDataBaseDAO.updateGlobalTransactionDO(globalTransactionDO));
-
- rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- Assertions.assertEquals(2, rs.getInt("status"));
- }else{
- Assertions.assertTrue(false);
- }
- rs.close();
-
- //delete
- conn.createStatement().execute(delSql);
-
- }finally {
- if(conn != null){
- conn.close();
- }
- }
-
- }
-
- @Test
- public void deleteGlobalTransactionDO() throws SQLException {
- GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
- globalTransactionDO.setXid("abc-123:555");
- globalTransactionDO.setApplicationData("abc=5454");
- globalTransactionDO.setTransactionServiceGroup("abc");
- globalTransactionDO.setTransactionName("test");
- globalTransactionDO.setTransactionId(12345);
- globalTransactionDO.setTimeout(20);
- globalTransactionDO.setBeginTime(System.currentTimeMillis());
- globalTransactionDO.setApplicationId("test");
- globalTransactionDO.setStatus(1);
-
- boolean ret = logStoreDataBaseDAO.insertGlobalTransactionDO(globalTransactionDO);
- Assertions.assertTrue(ret);
-
- //delete
- Assertions.assertTrue(logStoreDataBaseDAO.deleteGlobalTransactionDO(globalTransactionDO));
-
- //check
-
- String sql = "select * from global_table where xid= 'abc-123:555'";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(false);
- }else{
- Assertions.assertTrue(true);
- }
- rs.close();
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
- @Test
- public void queryBranchTransactionDO() throws SQLException {
- {
- //creata data for test
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceId("qqqq");
- branchTransactionDO.setXid("abc-123:6789");
- branchTransactionDO.setTransactionId(24234235);
- branchTransactionDO.setBranchId(345465676);
- branchTransactionDO.setBranchType("TCC");
- branchTransactionDO.setResourceGroupId("abc");
- branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
- branchTransactionDO.setResourceGroupId("a");
- branchTransactionDO.setClientId("1.1.1.1");
- branchTransactionDO.setStatus(1);
- branchTransactionDO.setApplicationData("abc=123");
- branchTransactionDO.setResourceGroupId("test");
-
- boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
- Assertions.assertTrue(ret);
- }
- {
- //creata data for test
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceId("qqqq");
- branchTransactionDO.setXid("abc-123:6789");
- branchTransactionDO.setTransactionId(24234235);
- branchTransactionDO.setBranchId(78563453);
- branchTransactionDO.setBranchType("TCC");
- branchTransactionDO.setResourceGroupId("abc");
- branchTransactionDO.setLockKey("t:6;t2:7");
- branchTransactionDO.setResourceGroupId("a");
- branchTransactionDO.setClientId("1.1.1.1");
- branchTransactionDO.setStatus(1);
- branchTransactionDO.setApplicationData("abc=123");
- branchTransactionDO.setResourceGroupId("test");
-
- boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
- Assertions.assertTrue(ret);
- }
-
- List rets = logStoreDataBaseDAO.queryBranchTransactionDO("abc-123:6789");
- Assertions.assertTrue(CollectionUtils.isNotEmpty(rets));
- Assertions.assertEquals(2, rets.size());
-
- if(78563453 == rets.get(0).getBranchId() && 345465676 == rets.get(1).getBranchId()){
- Assertions.assertTrue(true);
- }else if(78563453 == rets.get(1).getBranchId() && 345465676 == rets.get(0).getBranchId()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
-
- String delSql = "delete from branch_table where xid= 'abc-123:6789' ";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
-
- conn.createStatement().execute(delSql);
-
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
- @Test
- public void insertBranchTransactionDO() throws SQLException {
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceId("qqqq");
- branchTransactionDO.setXid("abc-123:7777");
- branchTransactionDO.setTransactionId(1285343);
- branchTransactionDO.setBranchId(1234508);
- branchTransactionDO.setBranchType("TCC");
- branchTransactionDO.setResourceGroupId("abc");
- branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
- branchTransactionDO.setResourceGroupId("a");
- branchTransactionDO.setClientId("1.1.1.1");
- branchTransactionDO.setStatus(1);
- branchTransactionDO.setApplicationData("abc=123");
- branchTransactionDO.setResourceGroupId("test");
-
- boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
- Assertions.assertTrue(ret);
-
-
- String sql = "select * from branch_table where xid= 'abc-123:7777' and branch_id = 1234508";
- String delSql = "delete from branch_table where xid= 'abc-123:7777' and branch_id = 1234508";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
-
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
-
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
-
- }
-
- @Test
- public void updateBranchTransactionDO() throws SQLException {
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceId("qqqq");
- branchTransactionDO.setXid("abc-123:8888");
- branchTransactionDO.setTransactionId(1285343);
- branchTransactionDO.setBranchId(343434318);
- branchTransactionDO.setBranchType("TCC");
- branchTransactionDO.setResourceGroupId("abc");
- branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
- branchTransactionDO.setResourceGroupId("a");
- branchTransactionDO.setClientId("1.1.1.1");
- branchTransactionDO.setStatus(1);
- branchTransactionDO.setApplicationData("abc=123");
- branchTransactionDO.setResourceGroupId("test");
-
- boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
- Assertions.assertTrue(ret);
-
- branchTransactionDO.setStatus(3);
- Assertions.assertTrue(logStoreDataBaseDAO.updateBranchTransactionDO(branchTransactionDO));
-
- String sql = "select * from branch_table where xid= 'abc-123:8888' and branch_id = 343434318";
- String delSql = "delete from branch_table where xid= 'abc-123:8888' and branch_id = 343434318";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
-
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- Assertions.assertEquals(3, rs.getInt("status"));
- }else {
- Assertions.assertTrue(false);
- }
-
- conn.createStatement().execute(delSql);
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
- @Test
- public void deleteBranchTransactionDO() throws SQLException {
- BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
- branchTransactionDO.setResourceId("qqqq");
- branchTransactionDO.setXid("abc-123:9999");
- branchTransactionDO.setTransactionId(1285343);
- branchTransactionDO.setBranchId(34567798);
- branchTransactionDO.setBranchType("TCC");
- branchTransactionDO.setResourceGroupId("abc");
- branchTransactionDO.setLockKey("t:1,2,3;t2,4,5,6");
- branchTransactionDO.setResourceGroupId("a");
- branchTransactionDO.setClientId("1.1.1.1");
- branchTransactionDO.setStatus(1);
- branchTransactionDO.setApplicationData("abc=123");
- branchTransactionDO.setResourceGroupId("test");
-
- boolean ret = logStoreDataBaseDAO.insertBranchTransactionDO(branchTransactionDO);
- Assertions.assertTrue(ret);
-
-
- String sql = "select * from branch_table where xid= 'abc-123:9999' and branch_id = 34567798";
- String delSql = "delete from branch_table where xid= 'abc-123:9999' and branch_id = 34567798";
- Connection conn = null;
- try{
- conn = dataSource.getConnection();
-
- ResultSet rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(true);
- }else {
- Assertions.assertTrue(false);
- }
- rs.close();
-
- //delete
- logStoreDataBaseDAO.deleteBranchTransactionDO(branchTransactionDO);
-
- rs = conn.createStatement().executeQuery(sql);
- if(rs.next()){
- Assertions.assertTrue(false);
- }else {
- Assertions.assertTrue(true);
- }
- rs.close();
-
- }finally {
- if(conn != null){
- conn.close();
- }
- }
- }
-
-}
\ No newline at end of file
diff --git a/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java b/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java
deleted file mode 100644
index 663234beea1..00000000000
--- a/discovery/seata-discovery-core/src/test/java/io/seata/config/ConfigurationFactoryTest.java
+++ /dev/null
@@ -1,32 +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.config;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-/**
- * @author Geng Zhang
- */
-class ConfigurationFactoryTest {
-
- @Test
- void getInstance() {
- Configuration configuration = ConfigurationFactory.getInstance();
- // check singleton
- Assertions.assertEquals(configuration, ConfigurationFactory.getInstance());
- }
-}
\ No newline at end of file
diff --git a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
index ceedb26bd64..8687246b90f 100644
--- a/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
+++ b/discovery/seata-discovery-eureka/src/main/java/io/seata/discovery/registry/eureka/EurekaRegistryProvider.java
@@ -16,6 +16,7 @@
package io.seata.discovery.registry.eureka;
import io.seata.common.loader.LoadLevel;
+import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryProvider;
diff --git a/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java b/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
index d201ce29c22..1acd0db7f7e 100644
--- a/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
+++ b/discovery/seata-discovery-nacos/src/main/java/io/seata/discovery/registry/nacos/NacosRegistryProvider.java
@@ -16,6 +16,7 @@
package io.seata.discovery.registry.nacos;
import io.seata.common.loader.LoadLevel;
+import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryProvider;
diff --git a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
index 10bd29dcae9..4585a45b092 100644
--- a/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
+++ b/discovery/seata-discovery-redis/src/main/java/io/seata/discovery/registry/redis/RedisRegistryProvider.java
@@ -18,6 +18,8 @@
import io.seata.common.loader.LoadLevel;
import io.seata.discovery.registry.RegistryProvider;
import io.seata.discovery.registry.RegistryService;
+import io.seata.discovery.registry.RegistryProvider;
+import io.seata.discovery.registry.RegistryService;
/**
* @author xingfudeshi@gmail.com
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 1ea76541b20..9c1d87a8810 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
@@ -34,6 +34,7 @@
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
+import io.seata.discovery.registry.RegistryService;
import io.seata.discovery.registry.RegistryService;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
diff --git a/pom.xml b/pom.xml
index d657ed812a4..e3628dda535 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,7 +82,7 @@
- 0.6.0
+ 0.5.2
1.8
@@ -107,7 +107,6 @@
2.23.4
3.12.2
1.4.2
-
@@ -143,6 +142,7 @@
test
+
diff --git a/rm-datasource/pom.xml b/rm-datasource/pom.xml
index 3b1a0435f45..8ab21440bb4 100644
--- a/rm-datasource/pom.xml
+++ b/rm-datasource/pom.xml
@@ -48,17 +48,6 @@
caffeine
-
- commons-dbcp
- commons-dbcp
- test
-
-
- com.h2database
- h2
- test
-
-
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 40adc924fa6..b835dc354ab 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
@@ -37,6 +37,7 @@
import java.util.Calendar;
import java.util.List;
+import io.seata.rm.datasource.sql.struct.Null;
import io.seata.rm.datasource.sql.struct.Null;
/**
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java b/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
index dd5f1baa2c3..f6076f88204 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/AsyncWorker.java
@@ -178,7 +178,7 @@ private void doBranchCommits() {
int maxSize = xids.size() > branchIds.size() ? xids.size() : branchIds.size();
if(maxSize == UNDOLOG_DELETE_LIMIT_SIZE){
try {
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, conn);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, UNDOLOG_DELETE_LIMIT_SIZE, conn);
} catch (Exception ex) {
LOGGER.warn("Failed to batch delete undo log [" + branchIds + "/" + xids + "]", ex);
}
@@ -192,7 +192,7 @@ private void doBranchCommits() {
}
try {
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, conn);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, UNDOLOG_DELETE_LIMIT_SIZE, conn);
}catch (Exception ex) {
LOGGER.warn("Failed to batch delete undo log [" + branchIds + "/" + xids + "]", ex);
}
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java b/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
index 492d59be5f2..5279ad772d7 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/PreparedStatementProxy.java
@@ -20,6 +20,8 @@
import java.sql.SQLException;
import java.util.ArrayList;
+import io.seata.rm.datasource.exec.ExecuteTemplate;
+import io.seata.rm.datasource.exec.StatementCallback;
import io.seata.rm.datasource.exec.ExecuteTemplate;
import io.seata.rm.datasource.exec.StatementCallback;
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 955fc81c058..e0b1eb7ab68 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
@@ -19,6 +19,8 @@
import java.sql.SQLException;
import java.sql.Statement;
+import io.seata.rm.datasource.exec.ExecuteTemplate;
+import io.seata.rm.datasource.exec.StatementCallback;
import io.seata.rm.datasource.exec.ExecuteTemplate;
import io.seata.rm.datasource.exec.StatementCallback;
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 26507eb74f3..6a3f3f848b5 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
@@ -29,6 +29,8 @@
import io.seata.rm.datasource.sql.SQLRecognizer;
import io.seata.rm.datasource.sql.struct.TableMeta;
import io.seata.rm.datasource.sql.struct.TableRecords;
+import io.seata.rm.datasource.undo.KeywordChecker;
+import io.seata.rm.datasource.undo.KeywordCheckerFactory;
import io.seata.rm.datasource.undo.KeywordChecker;
import io.seata.rm.datasource.undo.KeywordCheckerFactory;
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
index 26d87cd1d38..be6537bfe12 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/sql/WhereRecognizer.java
@@ -17,6 +17,7 @@
import java.util.ArrayList;
+import io.seata.rm.datasource.ParametersHolder;
import io.seata.rm.datasource.ParametersHolder;
/**
diff --git a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
index 36f14f97203..779da87c8d1 100644
--- a/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
+++ b/rm-datasource/src/main/java/io/seata/rm/datasource/undo/AbstractUndoExecutor.java
@@ -15,25 +15,16 @@
*/
package io.seata.rm.datasource.undo;
-import com.alibaba.fastjson.JSON;
-import io.seata.common.util.StringUtils;
-import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
import io.seata.rm.datasource.DataCompareUtils;
import io.seata.rm.datasource.sql.struct.Field;
import io.seata.rm.datasource.sql.struct.KeyType;
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 org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
/**
* The type Abstract undo executor.
@@ -43,24 +34,6 @@
*/
public abstract class AbstractUndoExecutor {
- /**
- * Logger for AbstractUndoExecutor
- **/
- private static final Logger LOGGER = LoggerFactory.getLogger(AbstractUndoExecutor.class);
-
- /**
- * template of check sql
- *
- * TODO support multiple primary key
- */
- private static final String CHECK_SQL_TEMPLATE = "SELECT * FROM %s WHERE %s in (%s)";
-
- /**
- * Switch of undo data validation
- */
- public static final boolean IS_UNDO_DATA_VALIDATION_ENABLE = ConfigurationFactory.getInstance()
- .getBoolean(ConfigurationKeys.TRANSACTION_UNOD_DATA_VALIDATION, true);
-
/**
* The Sql undo log.
*/
@@ -99,10 +72,11 @@ public SQLUndoLog getSqlUndoLog() {
*/
public void executeOn(Connection conn) throws SQLException {
- if (IS_UNDO_DATA_VALIDATION_ENABLE && !dataValidationAndGoOn(conn)) {
+ // no need undo if the before data snapshot is equivalent to the after data snapshot.
+ if (DataCompareUtils.isRecordsEquals(sqlUndoLog.getBeforeImage(), sqlUndoLog.getAfterImage())) {
return;
}
-
+ dataValidation(conn);
try {
String undoSQL = buildUndoSQL();
@@ -171,125 +145,9 @@ protected void undoPrepare(PreparedStatement undoPST, ArrayList undoValue
* Data validation.
*
* @param conn the conn
- * @return return true if data validation is ok and need continue undo, and return false if no need continue undo.
- * @throws SQLException the sql exception such as has dirty data
- */
- protected boolean dataValidationAndGoOn(Connection conn) throws SQLException {
-
- TableRecords beforeRecords = sqlUndoLog.getBeforeImage();
- TableRecords afterRecords = sqlUndoLog.getAfterImage();
-
- // Compare current data with before data
- // No need undo if the before data snapshot is equivalent to the after data snapshot.
- if (DataCompareUtils.isRecordsEquals(beforeRecords, afterRecords)) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info("Stop rollback because there is no data change " +
- "between the before data snapshot and the after data snapshot.");
- }
- // no need continue undo.
- return false;
- }
-
- // Validate if data is dirty.
- TableRecords currentRecords = queryCurrentRecords(conn);
- // compare with current data and after image.
- if (!DataCompareUtils.isRecordsEquals(afterRecords, currentRecords)) {
-
- // If current data is not equivalent to the after data, then compare the current data with the before
- // data, too. No need continue to undo if current data is equivalent to the before data snapshot
- if (DataCompareUtils.isRecordsEquals(beforeRecords, currentRecords)) {
- if (LOGGER.isInfoEnabled()) {
- LOGGER.info("Stop rollback because there is no data change " +
- "between the before data snapshot and the current data snapshot.");
- }
- // no need continue undo.
- return false;
- } else {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("check dirty datas failed, old and new data are not equal," +
- "tableName:[" + sqlUndoLog.getTableName() + "]," +
- "oldRows:[" + JSON.toJSONString(afterRecords.getRows()) + "]," +
- "newRows:[" + JSON.toJSONString(currentRecords.getRows()) + "].");
- }
- throw new SQLException("Has dirty records when undo.");
- }
- }
- return true;
- }
-
- /**
- * Query current records.
- *
- * @param conn the conn
- * @return the table records
* @throws SQLException the sql exception
*/
- protected TableRecords queryCurrentRecords(Connection conn) throws SQLException {
- TableRecords undoRecords = getUndoRows();
- TableMeta tableMeta = undoRecords.getTableMeta();
- String pkName = tableMeta.getPkName();
- int pkType = tableMeta.getColumnMeta(pkName).getDataType();
-
- // pares pk values
- Object[] pkValues = parsePkValues(getUndoRows());
- if (pkValues.length == 0) {
- return TableRecords.empty(tableMeta);
- }
- StringBuffer replace = new StringBuffer();
- for (int i = 0; i < pkValues.length; i++) {
- replace.append("?,");
- }
- // build check sql
- String checkSQL = String.format(CHECK_SQL_TEMPLATE, sqlUndoLog.getTableName(), pkName,
- replace.substring(0, replace.length() - 1));
-
- PreparedStatement statement = null;
- ResultSet checkSet = null;
- TableRecords currentRecords;
- try {
- statement = conn.prepareStatement(checkSQL);
- for (int i = 1; i <= pkValues.length; i++) {
- statement.setObject(i, pkValues[i - 1], pkType);
- }
- checkSet = statement.executeQuery();
- currentRecords = TableRecords.buildRecords(tableMeta, checkSet);
- } finally {
- if (checkSet != null) {
- try {
- checkSet.close();
- } catch (Exception e) {
- }
- }
- if (statement != null) {
- try {
- statement.close();
- } catch (Exception e) {
- }
- }
- }
- return currentRecords;
- }
-
- /**
- * Parse pk values object [ ].
- *
- * @param records the records
- * @return the object [ ]
- */
- protected Object[] parsePkValues(TableRecords records) {
- String pkName = records.getTableMeta().getPkName();
- List undoRows = records.getRows();
- Object[] pkValues = new Object[undoRows.size()];
- for (int i = 0; i < undoRows.size(); i++) {
- List fields = undoRows.get(i).getFields();
- if (fields != null) {
- for (Field field : fields) {
- if (StringUtils.equalsIgnoreCase(pkName, field.getName())) {
- pkValues[i] = field.getValue();
- }
- }
- }
- }
- return pkValues;
+ protected void dataValidation(Connection conn) throws SQLException {
+ // Validate if data is dirty.
}
}
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 deadf563778..ab278f2e71f 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
@@ -18,6 +18,7 @@
import com.alibaba.druid.util.JdbcConstants;
import io.seata.common.exception.NotSupportYetException;
import io.seata.common.util.BlobUtils;
+import io.seata.common.util.StringUtils;
import io.seata.core.exception.TransactionException;
import io.seata.rm.datasource.ConnectionContext;
import io.seata.rm.datasource.ConnectionProxy;
@@ -160,7 +161,7 @@ public static void undo(DataSourceProxy dataSourceProxy, String xid, long branch
}
Blob b = rs.getBlob("rollback_info");
- String rollbackInfo = BlobUtils.blob2string(b);
+ String rollbackInfo = StringUtils.blob2string(b);
BranchUndoLog branchUndoLog = UndoLogParserFactory.getInstance().decode(rollbackInfo);
for (SQLUndoLog sqlUndoLog : branchUndoLog.getSqlUndoLogs()) {
@@ -233,12 +234,13 @@ public static void undo(DataSourceProxy dataSourceProxy, String xid, long branch
*
* @param xids
* @param branchIds
+ * @param limitSize
* @param conn
*/
- public static void batchDeleteUndoLog(Set xids, Set branchIds, Connection conn) throws SQLException {
+ public static void batchDeleteUndoLog(Set xids, Set branchIds, int limitSize, Connection conn) throws SQLException {
int xidSize = xids.size();
int branchIdSize = branchIds.size();
- String batchDeleteSql = toBatchDeleteUndoLogSql(xidSize, branchIdSize);
+ String batchDeleteSql = toBatchDeleteUndoLogSql(xidSize, branchIdSize,limitSize);
PreparedStatement deletePST = null;
try {
deletePST = conn.prepareStatement(batchDeleteSql);
@@ -266,14 +268,15 @@ public static void batchDeleteUndoLog(Set xids, Set branchIds, Con
}
- protected static String toBatchDeleteUndoLogSql(int xidSize, int branchIdSize) {
+ protected static String toBatchDeleteUndoLogSql(int xidSize, int branchIdSize,int limitSize) {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("DELETE FROM ")
.append(UNDO_LOG_TABLE_NAME)
.append(" WHERE branch_id IN ");
- appendInParam(branchIdSize, sqlBuilder);
- sqlBuilder.append(" AND xid IN ");
appendInParam(xidSize, sqlBuilder);
+ sqlBuilder.append(" AND xid IN ");
+ appendInParam(branchIdSize, sqlBuilder);
+ sqlBuilder.append(" LIMIT ").append(limitSize);
return sqlBuilder.toString();
}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
deleted file mode 100644
index 0d79fa178d0..00000000000
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/AbstractUndoExecutorTest.java
+++ /dev/null
@@ -1,316 +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.rm.datasource.undo;
-
-import io.seata.rm.datasource.sql.SQLType;
-import io.seata.rm.datasource.sql.struct.ColumnMeta;
-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 org.apache.commons.dbcp.BasicDataSource;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-
-import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.sql.Types;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Geng Zhang
- */
-public class AbstractUndoExecutorTest extends BaseExecutorTest {
-
- static BasicDataSource dataSource = null;
-
- static Connection connection = null;
-
- static TableMeta tableMeta = null;
-
- @BeforeAll
- public static void start() throws SQLException {
- dataSource = new BasicDataSource();
- dataSource.setDriverClassName("org.h2.Driver");
- dataSource.setUrl("jdbc:h2:./db_store/test_undo");
- dataSource.setUsername("sa");
- dataSource.setPassword("");
-
- connection = dataSource.getConnection();
-
- tableMeta = mockTableMeta();
- }
-
- @AfterAll
- public static void stop() {
- if (connection != null) {
- try {
- connection.close();
- } catch (SQLException e) {
- }
- }
- if (dataSource != null) {
- try {
- dataSource.close();
- } catch (SQLException e) {
- }
- }
- }
-
- @BeforeEach
- private void prepareTable() {
- execSQL("DROP TABLE table_name");
- execSQL("CREATE TABLE table_name ( `id` int(8), `name` varchar(64), PRIMARY KEY (`id`))");
- }
-
- @Test
- public void dataValidationUpdate() throws SQLException {
- execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
- execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
-
- TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- execSQL("update table_name set name = 'xxx' where id in (12345, 12346);");
-
- TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- SQLUndoLog sqlUndoLog = new SQLUndoLog();
- sqlUndoLog.setSqlType(SQLType.UPDATE);
- sqlUndoLog.setTableMeta(tableMeta);
- sqlUndoLog.setTableName("table_name");
- sqlUndoLog.setBeforeImage(beforeImage);
- sqlUndoLog.setAfterImage(afterImage);
-
- TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, false);
-
- // case1: normal case before:aaa -> after:xxx -> current:xxx
- Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
-
- // case2: dirty data before:aaa -> after:xxx -> current:yyy
- execSQL("update table_name set name = 'yyy' where id in (12345, 12346);");
- try {
- spy.dataValidationAndGoOn(connection);
- Assertions.fail();
- } catch (Exception e) {
- Assertions.assertTrue(e instanceof SQLException);
- }
-
- // case 3: before == current before:aaa -> after:xxx -> current:aaa
- execSQL("update table_name set name = 'aaa' where id in (12345, 12346);");
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
-
- // case 4: before == after before:aaa -> after:aaa
- afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
- sqlUndoLog.setAfterImage(afterImage);
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
- }
-
- @Test
- public void dataValidationInsert() throws SQLException {
- TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
- execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
-
- TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- SQLUndoLog sqlUndoLog = new SQLUndoLog();
- sqlUndoLog.setSqlType(SQLType.INSERT);
- sqlUndoLog.setTableMeta(tableMeta);
- sqlUndoLog.setTableName("table_name");
- sqlUndoLog.setBeforeImage(beforeImage);
- sqlUndoLog.setAfterImage(afterImage);
-
- TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, false);
-
- // case1: normal case before:0 -> after:2 -> current:2
- Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
-
- // case2: dirty data before:0 -> after:2 -> current:2'
- execSQL("update table_name set name = 'yyy' where id in (12345, 12346);");
- try {
- Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
- Assertions.fail();
- } catch (Exception e) {
- Assertions.assertTrue(e instanceof SQLException);
- }
-
- // case3: before == current before:0 -> after:2 -> current:0
- execSQL("delete from table_name where id in (12345, 12346);");
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
-
- // case 4: before == after before:0 -> after:0
- afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
- sqlUndoLog.setAfterImage(afterImage);
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
- }
-
- @Test
- public void dataValidationDelete() throws SQLException {
- execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
- execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
-
- TableRecords beforeImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- execSQL("delete from table_name where id in (12345, 12346);");
-
- TableRecords afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
-
- SQLUndoLog sqlUndoLog = new SQLUndoLog();
- sqlUndoLog.setSqlType(SQLType.INSERT);
- sqlUndoLog.setTableMeta(tableMeta);
- sqlUndoLog.setTableName("table_name");
- sqlUndoLog.setBeforeImage(beforeImage);
- sqlUndoLog.setAfterImage(afterImage);
-
- TestUndoExecutor spy = new TestUndoExecutor(sqlUndoLog, true);
-
- // case1: normal case before:2 -> after:0 -> current:0
- Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
-
- // case2: dirty data before:2 -> after:0 -> current:1
- execSQL("INSERT INTO table_name(id, name) VALUES (12345,'aaa');");
- try {
- Assertions.assertTrue(spy.dataValidationAndGoOn(connection));
- Assertions.fail();
- } catch (Exception e) {
- Assertions.assertTrue(e instanceof SQLException);
- }
-
- // case3: before == current before:2 -> after:0 -> current:2
- execSQL("INSERT INTO table_name(id, name) VALUES (12346,'aaa');");
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
-
- // case 4: before == after before:2 -> after:2
- afterImage = execQuery(tableMeta, "SELECT * FROM table_name WHERE id IN (12345, 12346);");
- sqlUndoLog.setAfterImage(afterImage);
- Assertions.assertFalse(spy.dataValidationAndGoOn(connection));
- }
-
- @Test
- public void testParsePK() {
- TableMeta tableMeta = Mockito.mock(TableMeta.class);
- Mockito.when(tableMeta.getPkName()).thenReturn("id");
- Mockito.when(tableMeta.getTableName()).thenReturn("table_name");
-
- TableRecords beforeImage = new TableRecords();
- beforeImage.setTableName("table_name");
- beforeImage.setTableMeta(tableMeta);
-
- List beforeRows = new ArrayList<>();
- Row row0 = new Row();
- Field field01 = addField(row0, "id", 1, "12345");
- Field field02 = addField(row0, "age", 1, "2");
- beforeRows.add(row0);
- Row row1 = new Row();
- Field field11 = addField(row1, "id", 1, "12346");
- Field field12 = addField(row1, "age", 1, "2");
- beforeRows.add(row1);
- beforeImage.setRows(beforeRows);
-
- SQLUndoLog sqlUndoLog = new SQLUndoLog();
- sqlUndoLog.setSqlType(SQLType.UPDATE);
- sqlUndoLog.setTableMeta(tableMeta);
- sqlUndoLog.setTableName("table_name");
- sqlUndoLog.setBeforeImage(beforeImage);
- sqlUndoLog.setAfterImage(null);
-
- TestUndoExecutor executor = new TestUndoExecutor(sqlUndoLog, true);
- Object[] pkValues = executor.parsePkValues(beforeImage);
- Assertions.assertEquals(2, pkValues.length);
- }
-
-
- private static TableMeta mockTableMeta() {
- TableMeta tableMeta = Mockito.mock(TableMeta.class);
- Mockito.when(tableMeta.getPkName()).thenReturn("ID");
- Mockito.when(tableMeta.getTableName()).thenReturn("table_name");
- ColumnMeta meta0 = Mockito.mock(ColumnMeta.class);
- Mockito.when(meta0.getDataType()).thenReturn(Types.INTEGER);
- Mockito.when(meta0.getColumnName()).thenReturn("ID");
- Mockito.when(tableMeta.getColumnMeta("ID")).thenReturn(meta0);
- ColumnMeta meta1 = Mockito.mock(ColumnMeta.class);
- Mockito.when(meta1.getDataType()).thenReturn(Types.VARCHAR);
- Mockito.when(meta1.getColumnName()).thenReturn("NAME");
- Mockito.when(tableMeta.getColumnMeta("NAME")).thenReturn(meta1);
- return tableMeta;
- }
-
- private void execSQL(String sql) {
- Statement s = null;
- try {
- s = connection.createStatement();
- s.execute(sql);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if (s != null) {
- try {
- s.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-
- private TableRecords execQuery(TableMeta tableMeta, String sql) throws SQLException {
- Statement s = null;
- ResultSet set = null;
- try {
- s = connection.createStatement();
- set = s.executeQuery(sql);
- return TableRecords.buildRecords(tableMeta, set);
- } finally {
- if (set != null) {
- try {
- set.close();
- } catch (Exception e) {
- }
- }
- if (s != null) {
- try {
- s.close();
- } catch (SQLException e) {
- }
- }
- }
- }
-}
-
-class TestUndoExecutor extends AbstractUndoExecutor {
- private boolean isDelete;
- public TestUndoExecutor(SQLUndoLog sqlUndoLog, boolean isDelete) {
- super(sqlUndoLog);
- this.isDelete = isDelete;
- }
-
- @Override
- protected String buildUndoSQL() {
- return null;
- }
-
- @Override
- protected TableRecords getUndoRows() {
- return isDelete ? sqlUndoLog.getBeforeImage() : sqlUndoLog.getAfterImage();
- }
-}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
index ae1174c8c5c..eb7a0324bb2 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoExecutorTest.java
@@ -59,7 +59,6 @@
import io.seata.rm.datasource.sql.struct.TableRecords;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
/**
* The type Undo executor test.
@@ -89,7 +88,7 @@ public void testField() {
* Test update.
*/
@Test
- public void testUpdate() throws SQLException {
+ public void testUpdate() {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.UPDATE);
@@ -148,18 +147,19 @@ public void testUpdate() throws SQLException {
SQLUndoLog.setAfterImage(afterImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
- MockConnection connection = new MockConnection();
- AbstractUndoExecutor spy = Mockito.spy(executor);
- // skip data validation
- Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
- spy.executeOn(connection);
+
+ try {
+ executor.executeOn(new MockConnection());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
}
/**
* Test insert.
*/
@Test
- public void testInsert() throws SQLException {
+ public void testInsert() {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.INSERT);
@@ -217,18 +217,19 @@ public void testInsert() throws SQLException {
SQLUndoLog.setAfterImage(afterImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
- MockConnection connection = new MockConnection();
- AbstractUndoExecutor spy = Mockito.spy(executor);
- // skip data validation
- Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
- spy.executeOn(connection);
+
+ try {
+ executor.executeOn(new MockConnection());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
}
/**
* Test delete.
*/
@Test
- public void testDelete() throws SQLException {
+ public void testDelete() {
SQLUndoLog SQLUndoLog = new SQLUndoLog();
SQLUndoLog.setTableName("my_test_table");
SQLUndoLog.setSqlType(SQLType.DELETE);
@@ -286,11 +287,12 @@ public void testDelete() throws SQLException {
SQLUndoLog.setBeforeImage(beforeImage);
AbstractUndoExecutor executor = UndoExecutorFactory.getUndoExecutor(JdbcConstants.MYSQL, SQLUndoLog);
- MockConnection connection = new MockConnection();
- AbstractUndoExecutor spy = Mockito.spy(executor);
- // skip data validation
- Mockito.doReturn(true).when(spy).dataValidationAndGoOn(connection);
- spy.executeOn(connection);
+
+ try {
+ executor.executeOn(new MockConnection());
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
}
/**
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
index e8fe5504dc9..dcc8f5d4ddc 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/UndoLogManagerTest.java
@@ -40,10 +40,9 @@ public class UndoLogManagerTest {
private static final int APPEND_IN_SIZE = 10;
+ private static final int LIMIT_SIZE = 10;
- private static final String THE_APPEND_IN_SIZE_PARAM_STRING = " (?,?,?,?,?,?,?,?,?,?) ";
-
- private static final String THE_DOUBLE_APPEND_IN_SIZE_PARAM_STRING = " (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
+ private static final String THE_APPEND_IN_SIZE_PARAM_String = " (?,?,?,?,?,?,?,?,?,?) ";
@Test
public void testBatchDeleteUndoLog() throws Exception {
@@ -58,7 +57,7 @@ public void testBatchDeleteUndoLog() throws Exception {
Connection connection = mock(Connection.class);
PreparedStatement preparedStatement = mock(PreparedStatement.class);
when(connection.prepareStatement(anyString())).thenReturn(preparedStatement);
- UndoLogManager.batchDeleteUndoLog(xids, branchIds, connection);
+ UndoLogManager.batchDeleteUndoLog(xids, branchIds, LIMIT_SIZE, connection);
//verify
for (int i = 1;i <= APPEND_IN_SIZE;i++){
@@ -73,10 +72,11 @@ public void testBatchDeleteUndoLog() throws Exception {
@Test
public void testToBatchDeleteUndoLogSql() {
String expectedSqlString="DELETE FROM undo_log WHERE branch_id IN " +
- THE_APPEND_IN_SIZE_PARAM_STRING +
+ THE_APPEND_IN_SIZE_PARAM_String +
" AND xid IN " +
- THE_DOUBLE_APPEND_IN_SIZE_PARAM_STRING;
- String batchDeleteUndoLogSql = UndoLogManager.toBatchDeleteUndoLogSql(APPEND_IN_SIZE * 2, APPEND_IN_SIZE);
+ THE_APPEND_IN_SIZE_PARAM_String +
+ " LIMIT " + LIMIT_SIZE;
+ String batchDeleteUndoLogSql = UndoLogManager.toBatchDeleteUndoLogSql(APPEND_IN_SIZE, APPEND_IN_SIZE, LIMIT_SIZE);
System.out.println(batchDeleteUndoLogSql);
assertThat(batchDeleteUndoLogSql).isEqualTo(expectedSqlString);
}
@@ -85,7 +85,7 @@ public void testToBatchDeleteUndoLogSql() {
public void testAppendInParam() {
StringBuilder sqlBuilder = new StringBuilder();
UndoLogManager.appendInParam(APPEND_IN_SIZE, sqlBuilder);
- assertThat(sqlBuilder.toString()).isEqualTo(THE_APPEND_IN_SIZE_PARAM_STRING);
+ assertThat(sqlBuilder.toString()).isEqualTo(THE_APPEND_IN_SIZE_PARAM_String);
}
}
diff --git a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
index a3fd52afb1a..879b77a88cd 100644
--- a/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
+++ b/rm-datasource/src/test/java/io/seata/rm/datasource/undo/mysql/keyword/MySQLKeywordCheckerTest.java
@@ -26,6 +26,7 @@
import io.seata.rm.datasource.undo.KeywordChecker;
import io.seata.rm.datasource.undo.KeywordCheckerFactory;
import io.seata.rm.datasource.undo.SQLUndoLog;
+import io.seata.rm.datasource.undo.UndoExecutorTest;
import io.seata.rm.datasource.undo.mysql.MySQLUndoDeleteExecutor;
import io.seata.rm.datasource.undo.mysql.MySQLUndoInsertExecutor;
import io.seata.rm.datasource.undo.mysql.MySQLUndoUpdateExecutor;
diff --git a/server/pom.xml b/server/pom.xml
index 870f8187e7a..55290bec0ee 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -45,24 +45,6 @@
${project.version}
-
-
- com.alibaba
- druid
-
-
- commons-dbcp
- commons-dbcp
-
-
- com.h2database
- h2
-
-
- mysql
- mysql-connector-java
-
-
diff --git a/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java b/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
index 89fcbe94740..d6655196eee 100644
--- a/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
+++ b/server/src/main/java/io/seata/server/AbstractTCInboundHandler.java
@@ -15,6 +15,7 @@
*/
package io.seata.server;
+import io.seata.common.XID;
import io.seata.core.exception.AbstractExceptionHandler;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.GlobalStatus;
@@ -105,7 +106,8 @@ public void execute(GlobalRollbackRequest request, GlobalRollbackResponse respon
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
TransactionException tex) {
super.onTransactionException(request, response, tex);
- GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid());
+ GlobalSession globalSession = SessionHolder.findGlobalSession(
+ XID.getTransactionId(request.getXid()));
if (globalSession != null) {
response.setGlobalStatus(globalSession.getStatus());
} else {
@@ -116,7 +118,8 @@ public void onTransactionException(GlobalRollbackRequest request, GlobalRollback
@Override
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
super.onException(request, response, rex);
- GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid());
+ GlobalSession globalSession = SessionHolder.findGlobalSession(
+ XID.getTransactionId(request.getXid()));
if (globalSession != null) {
response.setGlobalStatus(globalSession.getStatus());
} else {
diff --git a/server/src/main/java/io/seata/server/Server.java b/server/src/main/java/io/seata/server/Server.java
index 0cec9d18b87..92273a3e68f 100644
--- a/server/src/main/java/io/seata/server/Server.java
+++ b/server/src/main/java/io/seata/server/Server.java
@@ -42,7 +42,7 @@ public class Server {
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),
+ new LinkedBlockingQueue(MAX_TASK_QUEUE_SIZE),
new NamedThreadFactory("ServerHandlerThread", MAX_SERVER_POOL_SIZE), new ThreadPoolExecutor.CallerRunsPolicy());
/**
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 18c1e80395f..15063da2cb2 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCoordinator.java
@@ -16,17 +16,13 @@
package io.seata.server.coordinator;
import java.io.IOException;
-import java.time.Duration;
import java.util.Collection;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import io.seata.common.XID;
import io.seata.common.thread.NamedThreadFactory;
-import io.seata.common.util.CollectionUtils;
-import io.seata.core.constants.ConfigurationKeys;
-import io.seata.common.util.DurationUtil;
-import io.seata.config.ConfigurationFactory;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.BranchStatus;
import io.seata.core.model.BranchType;
@@ -82,44 +78,6 @@ public class DefaultCoordinator extends AbstractTCInboundHandler
private static final int TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS = 5000;
- /**
- * The Committing retry delay.
- */
- protected int committingRetryDelay = CONFIG.getInt(ConfigurationKeys.COMMITING_RETRY_DELAY, 5);
-
- /**
- * The Asyn committing retry delay.
- */
- protected int asynCommittingRetryDelay = CONFIG.getInt(ConfigurationKeys.ASYN_COMMITING_RETRY_DELAY, 5);
-
- /**
- * The Rollbacking retry delay.
- */
- protected int rollbackingRetryDelay = CONFIG.getInt(ConfigurationKeys.ROLLBACKING_RETRY_DELAY, 5);
-
- /**
- * The Timeout retry delay.
- */
- protected int timeoutRetryDelay = CONFIG.getInt(ConfigurationKeys.TIMEOUT_RETRY_DELAY, 5);
-
- private static final int ALWAYS_RETRY_BOUNDARY = 0;
-
- private static final Duration MAX_COMMIT_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(ConfigurationKeys.SERVICE_PREFIX + "max.commit.retry.timeout", DurationUtil.DEFAULT_DURATION, 100);
-
- private static final Duration MAX_ROLLBACK_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(ConfigurationKeys.SERVICE_PREFIX + "max.rollback.retry.timeout", DurationUtil.DEFAULT_DURATION, 100);
-
- private ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("RetryRollbacking", 1));
-
- private ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("RetryCommitting", 1));
-
- private ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("AsyncCommitting", 1));
-
- private ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
- new NamedThreadFactory("TxTimeoutCheck", 1));
-
private ServerMessageSender messageSender;
private Core core = CoreFactory.get();
@@ -198,7 +156,7 @@ public BranchStatus branchCommit(BranchType branchType, String xid, long branchI
request.setApplicationData(applicationData);
request.setBranchType(branchType);
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
if(globalSession == null){
return BranchStatus.PhaseTwo_Committed;
}
@@ -207,7 +165,9 @@ public BranchStatus branchCommit(BranchType branchType, String xid, long branchI
BranchCommitResponse response = (BranchCommitResponse)messageSender.sendSyncRequest(resourceId,
branchSession.getClientId(), request);
return response.getBranchStatus();
- } catch (IOException | TimeoutException e) {
+ } catch (IOException e) {
+ throw new TransactionException(FailedToSendBranchCommitRequest, branchId + "/" + xid, e);
+ } catch (TimeoutException e) {
throw new TransactionException(FailedToSendBranchCommitRequest, branchId + "/" + xid, e);
}
}
@@ -225,7 +185,7 @@ public BranchStatus branchRollback(BranchType branchType, String xid, long branc
request.setApplicationData(applicationData);
request.setBranchType(branchType);
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
if(globalSession == null){
return BranchStatus.PhaseTwo_Rollbacked;
}
@@ -234,34 +194,27 @@ public BranchStatus branchRollback(BranchType branchType, String xid, long branc
BranchRollbackResponse response = (BranchRollbackResponse)messageSender.sendSyncRequest(resourceId,
branchSession.getClientId(), request);
return response.getBranchStatus();
- } catch (IOException | TimeoutException e) {
+ } catch (IOException e) {
+ throw new TransactionException(FailedToSendBranchRollbackRequest, branchId + "/" + xid, e);
+ } catch (TimeoutException e) {
throw new TransactionException(FailedToSendBranchRollbackRequest, branchId + "/" + xid, e);
}
}
- /**
- * Timeout check.
- *
- * @throws TransactionException the transaction exception
- */
- protected void timeoutCheck() throws TransactionException {
+ private void timeoutCheck() throws TransactionException {
Collection allSessions = SessionHolder.getRootSessionManager().allSessions();
- if(CollectionUtils.isEmpty(allSessions)){
- return;
- }
if (allSessions.size() > 0 && LOGGER.isDebugEnabled()) {
LOGGER.debug("Transaction Timeout Check Begin: " + allSessions.size());
}
for (GlobalSession globalSession : allSessions) {
if (LOGGER.isDebugEnabled()) {
- LOGGER.debug(globalSession.getXid() + " " + globalSession.getStatus() + " " +
+ LOGGER.debug(globalSession.getTransactionId() + " " + globalSession.getStatus() + " " +
globalSession.getBeginTime() + " " + globalSession.getTimeout());
}
boolean shouldTimeout = globalSession.lockAndExcute(() -> {
if (globalSession.getStatus() != GlobalStatus.Begin || !globalSession.isTimeout()) {
return false;
}
- globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
globalSession.close();
globalSession.changeStatus(GlobalStatus.TimeoutRollbacking);
return true;
@@ -270,7 +223,7 @@ protected void timeoutCheck() throws TransactionException {
continue;
}
LOGGER.info(
- "Global transaction[" + globalSession.getXid() + "] is timeout and will be rolled back.");
+ "Global transaction[" + globalSession.getTransactionId() + "] is timeout and will be rolled back.");
globalSession.addSessionLifecycleListener(SessionHolder.getRetryRollbackingSessionManager());
SessionHolder.getRetryRollbackingSessionManager().addGlobalSession(globalSession);
@@ -282,129 +235,107 @@ protected void timeoutCheck() throws TransactionException {
}
- /**
- * Handle retry rollbacking.
- */
- protected void handleRetryRollbacking() {
+ private void handleRetryRollbacking() {
Collection rollbackingSessions = SessionHolder.getRetryRollbackingSessionManager().allSessions();
- if(CollectionUtils.isEmpty(rollbackingSessions)){
- return;
- }
- long now = System.currentTimeMillis();
for (GlobalSession rollbackingSession : rollbackingSessions) {
try {
- if(isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT.toMillis(), rollbackingSession.getBeginTime())){
- /**
- * Prevent thread safety issues
- */
- SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(rollbackingSession);
- LOGGER.error("GlobalSession rollback retry timeout [{}]", rollbackingSession.getTransactionId());
- continue;
- }
- rollbackingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalRollback(rollbackingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry rollbacking [{}] {} {}",
- rollbackingSession.getXid(), ex.getCode(), ex.getMessage());
+ rollbackingSession.getTransactionId(), ex.getCode(), ex.getMessage());
}
}
}
- /**
- * Handle retry committing.
- */
- protected void handleRetryCommitting() {
+ private void handleRetryCommitting() {
Collection committingSessions = SessionHolder.getRetryCommittingSessionManager().allSessions();
- if(CollectionUtils.isEmpty(committingSessions)){
- return;
- }
- long now = System.currentTimeMillis();
for (GlobalSession committingSession : committingSessions) {
try {
- if(isRetryTimeout(now, MAX_COMMIT_RETRY_TIMEOUT.toMillis(), committingSession.getBeginTime())){
- /**
- * Prevent thread safety issues
- */
- SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(committingSession);
- LOGGER.error("GlobalSession commit retry timeout [{}]", committingSession.getTransactionId());
- continue;
- }
- committingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalCommit(committingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to retry committing [{}] {} {}",
- committingSession.getXid(), ex.getCode(), ex.getMessage());
+ committingSession.getTransactionId(), ex.getCode(), ex.getMessage());
}
}
}
- private boolean isRetryTimeout(long now, long timeout, long beginTime){
- /**
- * Start timing when the session begin
- */
- if(timeout >= ALWAYS_RETRY_BOUNDARY &&
- now - beginTime > timeout){
- return true;
- }
- return false;
- }
-
- /**
- * Handle async committing.
- */
- protected void handleAsyncCommitting() {
+ private void handleAsyncCommitting() {
Collection asyncCommittingSessions = SessionHolder.getAsyncCommittingSessionManager()
.allSessions();
- if(CollectionUtils.isEmpty(asyncCommittingSessions)){
- return;
- }
for (GlobalSession asyncCommittingSession : asyncCommittingSessions) {
try {
- asyncCommittingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
core.doGlobalCommit(asyncCommittingSession, true);
} catch (TransactionException ex) {
LOGGER.info("Failed to async committing [{}] {} {}",
- asyncCommittingSession.getXid(), ex.getCode(), ex.getMessage());
+ asyncCommittingSession.getTransactionId(), ex.getCode(), ex.getMessage());
}
}
}
+ private ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("RetryRollbacking", 1));
+
+ private ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("RetryCommitting", 1));
+
+ private ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("AsyncCommitting", 1));
+
+ private ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
+ new NamedThreadFactory("TxTimeoutCheck", 1));
/**
* Init.
*/
public void init() {
- retryRollbacking.scheduleAtFixedRate(() -> {
- try {
- handleRetryRollbacking();
- } catch (Exception e) {
- LOGGER.info("Exception retry rollbacking ... ", e);
+ retryRollbacking.scheduleAtFixedRate(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ handleRetryRollbacking();
+ } catch (Exception e) {
+ LOGGER.info("Exception retry rollbacking ... ", e);
+ }
+
}
- }, 0, rollbackingRetryDelay, TimeUnit.SECONDS);
+ }, 0, 5, TimeUnit.MILLISECONDS);
+
+ retryCommitting.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ handleRetryCommitting();
+ } catch (Exception e) {
+ LOGGER.info("Exception retry committing ... ", e);
+ }
- retryCommitting.scheduleAtFixedRate(() -> {
- try {
- handleRetryCommitting();
- } catch (Exception e) {
- LOGGER.info("Exception retry committing ... ", e);
}
- }, 0, committingRetryDelay, TimeUnit.SECONDS);
+ }, 0, 5, TimeUnit.MILLISECONDS);
+
+ asyncCommitting.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ handleAsyncCommitting();
+ } catch (Exception e) {
+ LOGGER.info("Exception async committing ... ", e);
+ }
- asyncCommitting.scheduleAtFixedRate(() -> {
- try {
- handleAsyncCommitting();
- } catch (Exception e) {
- LOGGER.info("Exception async committing ... ", e);
}
- }, 0, asynCommittingRetryDelay, TimeUnit.SECONDS);
+ }, 0, 10, TimeUnit.MILLISECONDS);
+
+ timeoutCheck.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ timeoutCheck();
+ } catch (Exception e) {
+ LOGGER.info("Exception timeout checking ... ", e);
+ }
- timeoutCheck.scheduleAtFixedRate(() -> {
- try {
- timeoutCheck();
- } catch (Exception e) {
- LOGGER.info("Exception timeout checking ... ", e);
}
- }, 0, timeoutRetryDelay, TimeUnit.SECONDS);
+ }, 0, 2, TimeUnit.MILLISECONDS);
}
@Override
@@ -438,14 +369,14 @@ public void destroy() {
retryCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
asyncCommitting.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
timeoutCheck.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
- } catch (InterruptedException ignore) {
+ } catch (InterruptedException ingore) {
}
- // 2. second close netty flow
+ // 2. sencond close netty flow
if (messageSender instanceof RpcServer){
((RpcServer) messageSender).destroy();
}
- // 3. last destroy SessionHolder
+ // 3. last destory SessionHolder
SessionHolder.destory();
}
}
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 cd10d4281ba..1ba36763f1f 100644
--- a/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
+++ b/server/src/main/java/io/seata/server/coordinator/DefaultCore.java
@@ -23,7 +23,7 @@
import io.seata.core.model.GlobalStatus;
import io.seata.core.model.ResourceManagerInbound;
import io.seata.server.lock.LockManager;
-import io.seata.server.lock.LockerFactory;
+import io.seata.server.lock.LockManagerFactory;
import io.seata.server.session.BranchSession;
import io.seata.server.session.GlobalSession;
import io.seata.server.session.SessionHelper;
@@ -46,7 +46,7 @@ public class DefaultCore implements Core {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCore.class);
- private LockManager lockManager = LockerFactory.getLockManager();
+ private LockManager lockManager = LockManagerFactory.get();
private ResourceManagerInbound resourceManagerInbound;
@@ -58,7 +58,7 @@ public void setResourceManagerInbound(ResourceManagerInbound resourceManagerInbo
@Override
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
String applicationData, String lockKeys) throws TransactionException {
- GlobalSession globalSession = assertGlobalSessionNotNull(xid);
+ GlobalSession globalSession = assertGlobalSessionNotNull(XID.getTransactionId(xid));
return globalSession.lockAndExcute(() -> {
if (!globalSession.isActive()) {
throw new TransactionException(GlobalTransactionNotActive, "Current Status: " + globalSession.getStatus());
@@ -67,7 +67,6 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
throw new TransactionException(GlobalTransactionStatusInvalid,
globalSession.getStatus() + " while expecting " + GlobalStatus.Begin);
}
- globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
applicationData, lockKeys, clientId);
if (!branchSession.lock()) {
@@ -82,10 +81,10 @@ public Long branchRegister(BranchType branchType, String resourceId, String clie
});
}
- private GlobalSession assertGlobalSessionNotNull(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ private GlobalSession assertGlobalSessionNotNull(long transactionId) throws TransactionException {
+ GlobalSession globalSession = SessionHolder.findGlobalSession(transactionId);
if (globalSession == null) {
- throw new TransactionException(TransactionExceptionCode.GlobalTransactionNotExist, "" + xid + "");
+ throw new TransactionException(TransactionExceptionCode.GlobalTransactionNotExist, "" + transactionId + "");
}
return globalSession;
}
@@ -94,12 +93,11 @@ private GlobalSession assertGlobalSessionNotNull(String xid) throws TransactionE
@Override
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
String applicationData) throws TransactionException {
- GlobalSession globalSession = assertGlobalSessionNotNull(xid);
+ GlobalSession globalSession = assertGlobalSessionNotNull(XID.getTransactionId(xid));
BranchSession branchSession = globalSession.getBranch(branchId);
if (branchSession == null) {
throw new TransactionException(BranchTransactionNotExist);
}
- globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
globalSession.changeBranchStatus(branchSession, status);
}
@@ -107,7 +105,7 @@ public void branchReport(BranchType branchType, String xid, long branchId, Branc
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
throws TransactionException {
if (branchType == BranchType.AT) {
- return lockManager.isLockable(xid, resourceId, lockKeys);
+ return lockManager.isLockable(XID.getTransactionId(xid), resourceId, lockKeys);
} else {
return true;
}
@@ -123,19 +121,17 @@ public String begin(String applicationId, String transactionServiceGroup, String
session.begin();
- return session.getXid();
+ return XID.generateXID(session.getTransactionId());
}
@Override
public GlobalStatus commit(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
if (globalSession == null) {
return GlobalStatus.Finished;
}
- globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
// just lock changeStatus
boolean shouldCommit = globalSession.lockAndExcute(() -> {
- //the lock should release after branch commit
globalSession.closeAndClean(); // Highlight: Firstly, close the session, then no more branch can be registered.
if (globalSession.getStatus() == GlobalStatus.Begin) {
globalSession.changeStatus(GlobalStatus.Committing);
@@ -179,7 +175,7 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
} else {
SessionHelper.endCommitFailed(globalSession);
LOGGER.error("Finally, failed to commit global[{}] since branch[{}] commit failed",
- globalSession.getXid(), branchSession.getBranchId());
+ globalSession.getTransactionId(), branchSession.getBranchId());
return;
}
default:
@@ -193,7 +189,7 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
} else {
LOGGER.error(
"Failed to commit global[{}] since branch[{}] commit failed, will retry later.",
- globalSession.getXid(), branchSession.getBranchId());
+ globalSession.getTransactionId(), branchSession.getBranchId());
return;
}
@@ -210,11 +206,11 @@ public void doGlobalCommit(GlobalSession globalSession, boolean retrying) throws
}
if (globalSession.hasBranch()) {
- LOGGER.info("Global[{}] committing is NOT done.", globalSession.getXid());
+ LOGGER.info("Global[{}] committing is NOT done.", globalSession.getTransactionId());
return;
}
SessionHelper.endCommitted(globalSession);
- LOGGER.info("Global[{}] committing is successfully done.", globalSession.getXid());
+ LOGGER.info("Global[{}] committing is successfully done.", globalSession.getTransactionId());
}
private void asyncCommit(GlobalSession globalSession) throws TransactionException {
@@ -242,11 +238,10 @@ private void queueToRetryRollback(GlobalSession globalSession) throws Transactio
@Override
public GlobalStatus rollback(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
if (globalSession == null) {
return GlobalStatus.Finished;
}
- globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
// just lock changeStatus
boolean shouldRollBack = globalSession.lockAndExcute(() -> {
globalSession.close(); // Highlight: Firstly, close the session, then no more branch can be registered.
@@ -284,7 +279,7 @@ public void doGlobalRollback(GlobalSession globalSession, boolean retrying) thro
continue;
case PhaseTwo_RollbackFailed_Unretryable:
SessionHelper.endRollbackFailed(globalSession);
- LOGGER.error("Failed to rollback global[" + globalSession.getXid() + "] since branch["
+ LOGGER.error("Failed to rollback global[" + globalSession.getTransactionId() + "] since branch["
+ branchSession.getBranchId() + "] rollback failed");
return;
default:
@@ -309,7 +304,7 @@ public void doGlobalRollback(GlobalSession globalSession, boolean retrying) thro
@Override
public GlobalStatus getStatus(String xid) throws TransactionException {
- GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
+ GlobalSession globalSession = SessionHolder.findGlobalSession(XID.getTransactionId(xid));
return globalSession.getStatus();
}
}
diff --git a/server/src/main/java/io/seata/server/lock/AbstractLockManager.java b/server/src/main/java/io/seata/server/lock/AbstractLockManager.java
deleted file mode 100644
index a8db3a54d92..00000000000
--- a/server/src/main/java/io/seata/server/lock/AbstractLockManager.java
+++ /dev/null
@@ -1,117 +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.server.lock;
-
-import io.seata.common.XID;
-import io.seata.common.util.StringUtils;
-import io.seata.core.lock.RowLock;
-import io.seata.server.session.BranchSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The type Abstract lock manager.
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-public abstract class AbstractLockManager implements LockManager {
-
- /**
- * The constant LOGGER.
- */
- protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockManager.class);
-
- /**
- * Collect row locks list.`
- *
- * @param branchSession the branch session
- * @return the list
- */
- protected List collectRowLocks(BranchSession branchSession){
- List locks = new ArrayList<>();
- if(branchSession == null || StringUtils.isBlank(branchSession.getLockKey())){
- return locks;
- }
- String xid = branchSession.getXid();
- String resourceId = branchSession.getResourceId();
- long transactionId = branchSession.getTransactionId();
-
- String lockKey = branchSession.getLockKey();
-
- return collectRowLocks(lockKey, resourceId, xid, transactionId, branchSession.getBranchId());
- }
-
- /**
- * Collect row locks list.
- *
- * @param lockKey the lock key
- * @param resourceId the resource id
- * @param xid the xid
- * @return the list
- */
- protected List collectRowLocks(String lockKey, String resourceId, String xid) {
- return collectRowLocks(lockKey, resourceId, xid, XID.getTransactionId(xid), null);
- }
-
- /**
- * Collect row locks list.
- *
- * @param lockKey the lock key
- * @param resourceId the resource id
- * @param xid the xid
- * @param transactionId the transaction id
- * @param branchID the branch id
- * @return the list
- */
- protected List collectRowLocks(String lockKey, String resourceId, String xid, Long transactionId, Long branchID){
- List locks = new ArrayList();
-
- String[] tableGroupedLockKeys = lockKey.split(";");
- for (String tableGroupedLockKey : tableGroupedLockKeys) {
- int idx = tableGroupedLockKey.indexOf(":");
- if (idx < 0) {
- return locks;
- }
- String tableName = tableGroupedLockKey.substring(0, idx);
- String mergedPKs = tableGroupedLockKey.substring(idx + 1);
- if(StringUtils.isBlank(mergedPKs)){
- return locks;
- }
- String[] pks = mergedPKs.split(",");
- if(pks == null || pks.length == 0){
- return locks;
- }
- for(String pk : pks){
- if(StringUtils.isNotBlank(pk)){
- RowLock rowLock = new RowLock();
- rowLock.setXid(xid);
- rowLock.setTransactionId(transactionId);
- rowLock.setBranchId(branchID);
- rowLock.setTableName(tableName);
- rowLock.setPk(pk);
- rowLock.setResourceId(resourceId);
- locks.add(rowLock);
- }
- }
- }
- return locks;
- }
-
-}
diff --git a/server/src/main/java/io/seata/server/lock/DefaultLockManager.java b/server/src/main/java/io/seata/server/lock/DefaultLockManager.java
deleted file mode 100644
index dd66e979987..00000000000
--- a/server/src/main/java/io/seata/server/lock/DefaultLockManager.java
+++ /dev/null
@@ -1,103 +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.server.lock;
-
-import io.seata.common.util.CollectionUtils;
-import io.seata.common.util.StringUtils;
-import io.seata.core.exception.TransactionException;
-import io.seata.core.lock.Locker;
-import io.seata.core.lock.RowLock;
-import io.seata.server.session.BranchSession;
-
-import java.util.List;
-
-/**
- * The type Default lock manager.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-public class DefaultLockManager extends AbstractLockManager {
-
- private static Locker locker = null;
-
- @Override
- public boolean acquireLock(BranchSession branchSession) throws TransactionException {
- String lockKey = branchSession.getLockKey();
- if (StringUtils.isNullOrEmpty(lockKey)) {
- //no lock
- return true;
- }
- //get locks of branch
- List locks = collectRowLocks(branchSession);
- if(CollectionUtils.isEmpty(locks)){
- //no lock
- return true;
- }
- return getLocker(branchSession).acquireLock(locks);
- }
-
- @Override
- public boolean releaseLock(BranchSession branchSession) throws TransactionException {
- List locks = collectRowLocks(branchSession);
- if(CollectionUtils.isEmpty(locks)){
- //no lock
- return true;
- }
- try{
- return getLocker(branchSession).releaseLock(locks);
- }catch(Exception t){
- LOGGER.error("unLock error, branchSession:" + branchSession, t);
- return false;
- }
- }
-
- @Override
- public boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException {
- List locks = collectRowLocks(lockKey, resourceId, xid);
- try{
- return getLocker().isLockable(locks);
- }catch(Exception t){
- LOGGER.error("isLockable error, xid:" + xid + ", resourceId:"+resourceId + ", lockKey:"+lockKey, t);
- return false;
- }
- }
-
- @Override
- public void cleanAllLocks() throws TransactionException {
- getLocker().cleanAllLocks();
- }
-
- /**
- * Gets locker.
- *
- * @return the locker
- */
- protected Locker getLocker() {
- return getLocker(null);
- }
-
- /**
- * Gets locker.
- *
- * @param branchSession the branch session
- * @return the locker
- */
- protected Locker getLocker(BranchSession branchSession) {
- return LockerFactory.get(branchSession);
- }
-
-}
diff --git a/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java b/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java
new file mode 100644
index 00000000000..14a68549987
--- /dev/null
+++ b/server/src/main/java/io/seata/server/lock/DefaultLockManagerImpl.java
@@ -0,0 +1,186 @@
+/*
+ * 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.lock;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import io.netty.util.internal.ConcurrentSet;
+import io.seata.common.exception.ShouldNeverHappenException;
+import io.seata.common.util.StringUtils;
+import io.seata.core.exception.TransactionException;
+import io.seata.server.session.BranchSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The type Default lock manager.
+ *
+ * @author sharajava
+ */
+public class DefaultLockManagerImpl implements LockManager {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLockManagerImpl.class);
+
+ private static final int BUCKET_PER_TABLE = 128;
+
+ private static final
+ ConcurrentHashMap>>>
+ LOCK_MAP = new ConcurrentHashMap>>>();
+
+ @Override
+ public boolean acquireLock(BranchSession branchSession) throws TransactionException {
+ String resourceId = branchSession.getResourceId();
+ long transactionId = branchSession.getTransactionId();
+ ConcurrentHashMap>> dbLockMap = LOCK_MAP.get(resourceId);
+ if (dbLockMap == null) {
+ LOCK_MAP.putIfAbsent(resourceId,
+ new ConcurrentHashMap>>());
+ dbLockMap = LOCK_MAP.get(resourceId);
+ }
+ ConcurrentHashMap, Set> bucketHolder = branchSession.getLockHolder();
+
+ String lockKey = branchSession.getLockKey();
+ if (StringUtils.isNullOrEmpty(lockKey)) {
+ return true;
+ }
+
+ String[] tableGroupedLockKeys = lockKey.split(";");
+ for (String tableGroupedLockKey : tableGroupedLockKeys) {
+ int idx = tableGroupedLockKey.indexOf(":");
+ if (idx < 0) {
+ branchSession.unlock();
+ throw new ShouldNeverHappenException("Wrong format of LOCK KEYS: " + branchSession.getLockKey());
+ }
+ String tableName = tableGroupedLockKey.substring(0, idx);
+ String mergedPKs = tableGroupedLockKey.substring(idx + 1);
+ ConcurrentHashMap> tableLockMap = dbLockMap.get(tableName);
+ if (tableLockMap == null) {
+ dbLockMap.putIfAbsent(tableName, new ConcurrentHashMap>());
+ tableLockMap = dbLockMap.get(tableName);
+ }
+ String[] pks = mergedPKs.split(",");
+ for (String pk : pks) {
+ int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
+ Map bucketLockMap = tableLockMap.get(bucketId);
+ if (bucketLockMap == null) {
+ tableLockMap.putIfAbsent(bucketId, new HashMap());
+ bucketLockMap = tableLockMap.get(bucketId);
+ }
+ synchronized (bucketLockMap) {
+ Long lockingTransactionId = bucketLockMap.get(pk);
+ if (lockingTransactionId == null) {
+ // No existing lock
+ bucketLockMap.put(pk, transactionId);
+ Set keysInHolder = bucketHolder.get(bucketLockMap);
+ if (keysInHolder == null) {
+ bucketHolder.putIfAbsent(bucketLockMap, new ConcurrentSet());
+ keysInHolder = bucketHolder.get(bucketLockMap);
+ }
+ keysInHolder.add(pk);
+
+ } else if (lockingTransactionId.longValue() == transactionId) {
+ // Locked by me
+ continue;
+ } else {
+ LOGGER.info(
+ "Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
+ branchSession.unlock(); // Release all acquired locks.
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isLockable(long transactionId, String resourceId, String lockKey) throws TransactionException {
+ ConcurrentHashMap>> dbLockMap = LOCK_MAP.get(resourceId);
+ if (dbLockMap == null) {
+ return true;
+ }
+ String[] tableGroupedLockKeys = lockKey.split(";");
+ for (String tableGroupedLockKey : tableGroupedLockKeys) {
+ int idx = tableGroupedLockKey.indexOf(":");
+ if (idx < 0) {
+ throw new ShouldNeverHappenException("Wrong format of LOCK KEYS: " + lockKey);
+ }
+ String tableName = tableGroupedLockKey.substring(0, idx);
+ String mergedPKs = tableGroupedLockKey.substring(idx + 1);
+ ConcurrentHashMap> tableLockMap = dbLockMap.get(tableName);
+ if (tableLockMap == null) {
+ continue;
+ }
+ String[] pks = mergedPKs.split(",");
+ for (String pk : pks) {
+ int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
+ Map bucketLockMap = tableLockMap.get(bucketId);
+ if (bucketLockMap == null) {
+ continue;
+ }
+ Long lockingTransactionId = bucketLockMap.get(pk);
+ if (lockingTransactionId == null || lockingTransactionId.longValue() == transactionId) {
+ // Locked by me
+ continue;
+ } else {
+ LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void cleanAllLocks() throws TransactionException {
+ LOCK_MAP.clear();
+ }
+
+ @Override
+ public boolean releaseLock(BranchSession branchSession) throws TransactionException {
+ ConcurrentHashMap, Set> lockHolder = branchSession.getLockHolder();
+ if (lockHolder.size() == 0) {
+ return true;
+ }
+ Iterator, Set>> it = lockHolder.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry, Set> entry = it.next();
+ Map bucket = entry.getKey();
+ Set keys = entry.getValue();
+ synchronized (bucket) {
+ for (String key : keys) {
+ Long v = bucket.get(key);
+ if (v == null) {
+ continue;
+ }
+ if (v.longValue() == branchSession.getTransactionId()) {
+ bucket.remove(key);
+ }
+ }
+ }
+ }
+ lockHolder.clear();
+ return true;
+ }
+}
diff --git a/server/src/main/java/io/seata/server/lock/LockManager.java b/server/src/main/java/io/seata/server/lock/LockManager.java
index 64e7bd7317e..54bcef3c0b4 100644
--- a/server/src/main/java/io/seata/server/lock/LockManager.java
+++ b/server/src/main/java/io/seata/server/lock/LockManager.java
@@ -35,30 +35,29 @@ public interface LockManager {
boolean acquireLock(BranchSession branchSession) throws TransactionException;
/**
- * Un lock boolean.
+ * Is lockable boolean.
*
- * @param branchSession the branch session
+ * @param transactionId the transaction id
+ * @param resourceId the resource id
+ * @param lockKey the lock key
* @return the boolean
* @throws TransactionException the transaction exception
*/
- boolean releaseLock(BranchSession branchSession) throws TransactionException;
+ boolean isLockable(long transactionId, String resourceId, String lockKey) throws TransactionException;
/**
- * Is lockable boolean.
+ * Clean all locks.
*
- * @param xid the xid
- * @param resourceId the resource id
- * @param lockKey the lock key
- * @return the boolean
* @throws TransactionException the transaction exception
*/
- boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException;
+ void cleanAllLocks() throws TransactionException;
/**
- * Clean all locks.
+ * Release lock boolean.
*
+ * @param branchSession the branch session
+ * @return the boolean
* @throws TransactionException the transaction exception
*/
- void cleanAllLocks() throws TransactionException;
-
+ boolean releaseLock(BranchSession branchSession) throws TransactionException;
}
diff --git a/server/src/main/java/io/seata/server/store/ReloadableStore.java b/server/src/main/java/io/seata/server/lock/LockManagerFactory.java
similarity index 54%
rename from server/src/main/java/io/seata/server/store/ReloadableStore.java
rename to server/src/main/java/io/seata/server/lock/LockManagerFactory.java
index d7b705c65a8..3468cc89449 100644
--- a/server/src/main/java/io/seata/server/store/ReloadableStore.java
+++ b/server/src/main/java/io/seata/server/lock/LockManagerFactory.java
@@ -13,34 +13,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.seata.server.store;
-
-import java.util.List;
+package io.seata.server.lock;
/**
- * The interface Reloadable store.
+ * The type Lock manager factory.
*
- * @author zhangsen
- * @data 2019 /4/24
+ * @author sharajava
*/
-public interface ReloadableStore {
+public class LockManagerFactory {
+
+ private static class SingletonHolder {
+ private static LockManager INSTANCE = new DefaultLockManagerImpl();
+ }
/**
- * Read write store.
+ * Get lock manager.
*
- * @param readSize the read size
- * @param isHistory the is history
- * @return the list
+ * @return the lock manager
*/
- List readWriteStore(int readSize, boolean isHistory);
+ public static final LockManager get() {
+ return SingletonHolder.INSTANCE;
+ }
/**
- * Has remaining boolean.
+ * Just for test mocking
*
- * @param isHistory the is history
- * @return the boolean
+ * @param lockManager the lock manager
*/
- boolean hasRemaining(boolean isHistory);
-
-
+ public static void set(LockManager lockManager) {
+ SingletonHolder.INSTANCE = lockManager;
+ }
}
diff --git a/server/src/main/java/io/seata/server/lock/LockerFactory.java b/server/src/main/java/io/seata/server/lock/LockerFactory.java
deleted file mode 100644
index 6a402f0a447..00000000000
--- a/server/src/main/java/io/seata/server/lock/LockerFactory.java
+++ /dev/null
@@ -1,99 +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.server.lock;
-
-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.db.DataSourceGenerator;
-import io.seata.server.session.BranchSession;
-
-import javax.sql.DataSource;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * The type Lock manager factory.
- *
- * @author sharajava
- */
-public class LockerFactory {
-
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
- /**
- * The constant locker.
- */
- protected static Locker locker = null;
-
- /**
- * The constant lockerMap.
- */
- protected static Map lockerMap = new ConcurrentHashMap<>();
-
- /**
- * The constant lockManager.
- */
- protected static LockManager lockManager = new DefaultLockManager();
-
- /**
- * Get lock manager.
- *
- * @return the lock manager
- */
- public static synchronized final LockManager getLockManager() {
- return lockManager;
- }
-
- /**
- * Get lock manager.
- *
- * @param branchSession the branch session
- * @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);
- }
- //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}, new Object[]{logStoreDataSource});
- lockerMap.put(lockMode, locker);
- }else if(LockMode.MEMORY.name().equalsIgnoreCase(lockMode)){
- if(branchSession == null){
- throw new IllegalArgumentException("branchSession can be null for memory lockMode.");
- }
- locker = EnhancedServiceLoader.load(Locker.class, lockMode,
- new Class[]{BranchSession.class}, new Object[]{branchSession} );
- }else {
- //other locker
- locker = EnhancedServiceLoader.load(Locker.class, lockMode);
- }
- 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
deleted file mode 100644
index 5721727fdc8..00000000000
--- a/server/src/main/java/io/seata/server/lock/db/DataBaseLocker.java
+++ /dev/null
@@ -1,101 +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.server.lock.db;
-
-import io.seata.common.loader.EnhancedServiceLoader;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.CollectionUtils;
-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 javax.sql.DataSource;
-import java.util.List;
-
-/**
- * The type Data base locker.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-@LoadLevel(name = "db")
-public class DataBaseLocker extends AbstractLocker {
-
- private LockStore lockStore;
-
- /**
- * Instantiates a new Data base locker.
- */
- public DataBaseLocker(){
- }
-
- /**
- * Instantiates a new Data base locker.
- *
- * @param logStoreDataSource the log store data source
- */
- public DataBaseLocker(DataSource logStoreDataSource){
- lockStore = EnhancedServiceLoader.load(LockStore.class, LockMode.DB.name(), new Class[]{DataSource.class}, new Object[]{logStoreDataSource});
- }
-
- @Override
- public boolean acquireLock(List locks) {
- if(CollectionUtils.isEmpty(locks)){
- //no lock
- return true;
- }
- try{
- return lockStore.acquireLock(convertToLockDO(locks));
- }catch(Exception t){
- LOGGER.error("AcquireLock error, locks:" + CollectionUtils.toString(locks), t);
- return false;
- }
- }
-
- @Override
- public boolean releaseLock(List locks) {
- if(CollectionUtils.isEmpty(locks)){
- //no lock
- return true;
- }
- try{
- return lockStore.unLock(convertToLockDO(locks));
- }catch(Exception t){
- LOGGER.error("unLock error, locks:" + CollectionUtils.toString(locks), t);
- return false;
- }
- }
-
- @Override
- public boolean isLockable(List locks) {
- try{
- return lockStore.isLockable(convertToLockDO(locks));
- }catch(Exception t){
- LOGGER.error("isLockable error, locks:" + CollectionUtils.toString(locks), t);
- return false;
- }
- }
-
- /**
- * Sets lock store.
- *
- * @param lockStore the lock store
- */
- public void setLockStore(LockStore lockStore) {
- this.lockStore = lockStore;
- }
-}
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
deleted file mode 100644
index f4dbb9423e6..00000000000
--- a/server/src/main/java/io/seata/server/lock/memory/MemoryLocker.java
+++ /dev/null
@@ -1,193 +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.server.lock.memory;
-
-import io.netty.util.internal.ConcurrentSet;
-import io.seata.common.exception.FrameworkException;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.CollectionUtils;
-import io.seata.core.exception.TransactionException;
-import io.seata.core.lock.AbstractLocker;
-import io.seata.core.lock.RowLock;
-import io.seata.server.session.BranchSession;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * The type Memory locker.
- *
- * @author zhangsen
- * @data 2019 -05-15
- */
-@LoadLevel(name="memory")
-public class MemoryLocker extends AbstractLocker {
-
- private static final int BUCKET_PER_TABLE = 128;
-
- private static final ConcurrentHashMap>>>
- LOCK_MAP = new ConcurrentHashMap>>>();
-
- /**
- * The Branch session.
- */
- protected BranchSession branchSession = null;
-
- /**
- * Instantiates a new Memory locker.
- *
- * @param branchSession the branch session
- */
- public MemoryLocker(BranchSession branchSession){
- this.branchSession = branchSession;
- }
-
- @Override
- public boolean acquireLock(List rowLocks) {
- if(CollectionUtils.isEmpty(rowLocks)){
- //no lock
- return true;
- }
- String resourceId = branchSession.getResourceId();
- long transactionId = branchSession.getTransactionId();
-
- ConcurrentHashMap, Set> bucketHolder = branchSession.getLockHolder();
- ConcurrentHashMap>> dbLockMap = LOCK_MAP.get(resourceId);
- if (dbLockMap == null) {
- LOCK_MAP.putIfAbsent(resourceId, new ConcurrentHashMap>>());
- dbLockMap = LOCK_MAP.get(resourceId);
- }
-
- for(RowLock lock : rowLocks){
- String tableName = lock.getTableName();
- String pk = lock.getPk();
- ConcurrentHashMap> tableLockMap = dbLockMap.get(tableName);
- if (tableLockMap == null) {
- dbLockMap.putIfAbsent(tableName, new ConcurrentHashMap>());
- tableLockMap = dbLockMap.get(tableName);
- }
- int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
- Map bucketLockMap = tableLockMap.get(bucketId);
- if (bucketLockMap == null) {
- tableLockMap.putIfAbsent(bucketId, new ConcurrentHashMap());
- bucketLockMap = tableLockMap.get(bucketId);
- }
- synchronized (bucketLockMap) {
- Long lockingTransactionId = bucketLockMap.get(pk);
- if (lockingTransactionId == null) {
- //No existing lock
- bucketLockMap.put(pk, transactionId);
- Set keysInHolder = bucketHolder.get(bucketLockMap);
- if (keysInHolder == null) {
- bucketHolder.putIfAbsent(bucketLockMap, new ConcurrentSet());
- keysInHolder = bucketHolder.get(bucketLockMap);
- }
- keysInHolder.add(pk);
-
- } else if (lockingTransactionId.longValue() == transactionId) {
- // Locked by me
- continue;
- } else {
- LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
- try {
- // Release all acquired locks.
- branchSession.unlock();
- } catch (TransactionException e) {
- throw new FrameworkException(e);
- }
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- public boolean releaseLock(List rowLock) {
- ConcurrentHashMap, Set> lockHolder = branchSession.getLockHolder();
- if (lockHolder == null || lockHolder.size() == 0) {
- return true;
- }
- Iterator, Set>> it = lockHolder.entrySet().iterator();
- while (it.hasNext()) {
- Map.Entry, Set> entry = it.next();
- Map bucket = entry.getKey();
- Set keys = entry.getValue();
- synchronized (bucket) {
- for (String key : keys) {
- Long v = bucket.get(key);
- if (v == null) {
- continue;
- }
- if (v.longValue() == branchSession.getTransactionId()) {
- bucket.remove(key);
- }
- }
- }
- }
- lockHolder.clear();
- return true;
- }
-
- @Override
- public boolean isLockable(List rowLocks) {
- if(CollectionUtils.isEmpty(rowLocks)){
- //no lock
- return true;
- }
- Long transactionId = rowLocks.get(0).getTransactionId();
- String resourceId = rowLocks.get(0).getResourceId();
- ConcurrentHashMap>> dbLockMap = LOCK_MAP.get(resourceId);
- if (dbLockMap == null) {
- return true;
- }
- for(RowLock rowLock : rowLocks){
- String xid = rowLock.getXid();
- String tableName = rowLock.getTableName();
- String pk = rowLock.getPk();
-
- ConcurrentHashMap> tableLockMap = dbLockMap.get(tableName);
- if (tableLockMap == null) {
- continue;
- }
- int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
- Map bucketLockMap = tableLockMap.get(bucketId);
- if (bucketLockMap == null) {
- continue;
- }
- Long lockingTransactionId = bucketLockMap.get(pk);
- if (lockingTransactionId == null || lockingTransactionId.longValue() == transactionId) {
- // Locked by me
- continue;
- } else {
- LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
- return false;
- }
- }
- return true;
- }
-
- @Override
- public void cleanAllLocks() {
- LOCK_MAP.clear();
- }
-}
diff --git a/server/src/main/java/io/seata/server/session/AbstractSessionManager.java b/server/src/main/java/io/seata/server/session/AbstractSessionManager.java
index 8cce5790b8f..d58f8b71d5a 100644
--- a/server/src/main/java/io/seata/server/session/AbstractSessionManager.java
+++ b/server/src/main/java/io/seata/server/session/AbstractSessionManager.java
@@ -25,8 +25,16 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* The type Abstract session manager.
+ *
+ * @author sharajava
*/
public abstract class AbstractSessionManager implements SessionManager, SessionLifecycleListener {
@@ -35,6 +43,11 @@ public abstract class AbstractSessionManager implements SessionManager, SessionL
*/
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractSessionManager.class);
+ /**
+ * The Session map.
+ */
+ protected Map sessionMap = new ConcurrentHashMap<>();
+
/**
* The Transaction store manager.
*/
@@ -45,12 +58,6 @@ public abstract class AbstractSessionManager implements SessionManager, SessionL
*/
protected String name;
- /**
- * Instantiates a new Abstract session manager.
- */
- public AbstractSessionManager() {
- }
-
/**
* Instantiates a new Abstract session manager.
*
@@ -66,6 +73,15 @@ public void addGlobalSession(GlobalSession session) throws TransactionException
LOGGER.debug("MANAGER[" + name + "] SESSION[" + session + "] " + LogOperation.GLOBAL_ADD);
}
writeSession(LogOperation.GLOBAL_ADD, session);
+ sessionMap.put(session.getTransactionId(), session);
+
+ }
+
+
+
+ @Override
+ public GlobalSession findGlobalSession(Long transactionId) {
+ return sessionMap.get(transactionId);
}
@Override
@@ -82,6 +98,8 @@ public void removeGlobalSession(GlobalSession session) throws TransactionExcepti
LOGGER.debug("MANAGER[" + name + "] SESSION[" + session + "] " + LogOperation.GLOBAL_REMOVE);
}
writeSession(LogOperation.GLOBAL_REMOVE, session);
+ sessionMap.remove(session.getTransactionId());
+
}
@Override
@@ -108,6 +126,23 @@ public void removeBranchSession(GlobalSession globalSession, BranchSession branc
LOGGER.debug("MANAGER[" + name + "] SESSION[" + branchSession + "] " + LogOperation.GLOBAL_ADD);
}
writeSession(LogOperation.BRANCH_REMOVE, branchSession);
+
+ }
+
+ @Override
+ public Collection allSessions() {
+ return sessionMap.values();
+ }
+
+ @Override
+ public List findGlobalSessions(SessionCondition condition) {
+ List found = new ArrayList<>();
+ for (GlobalSession globalSession : sessionMap.values()) {
+ if (System.currentTimeMillis() - globalSession.getBeginTime() > condition.getOverTimeAliveMills()) {
+ found.add(globalSession);
+ }
+ }
+ return found;
}
@Override
@@ -139,29 +174,18 @@ public void onRemoveBranch(GlobalSession globalSession, BranchSession branchSess
@Override
public void onClose(GlobalSession globalSession) throws TransactionException {
globalSession.setActive(false);
+
}
@Override
public void onEnd(GlobalSession globalSession) throws TransactionException {
removeGlobalSession(globalSession);
+
}
- private void writeSession(LogOperation logOperation, SessionStorable sessionStorable) throws TransactionException {
+ private void writeSession(LogOperation logOperation, SessionStorable sessionStorable) throws TransactionException{
if (!transactionStoreManager.writeSession(logOperation, sessionStorable)) {
throw new TransactionException(TransactionExceptionCode.FailedWriteSession);
}
}
-
- @Override
- public void destroy() {
- }
-
- /**
- * Sets transaction store manager.
- *
- * @param transactionStoreManager the transaction store manager
- */
- public void setTransactionStoreManager(TransactionStoreManager transactionStoreManager) {
- this.transactionStoreManager = transactionStoreManager;
- }
}
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 7354a88ab07..31e51961235 100644
--- a/server/src/main/java/io/seata/server/session/BranchSession.java
+++ b/server/src/main/java/io/seata/server/session/BranchSession.java
@@ -15,22 +15,22 @@
*/
package io.seata.server.session;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
import io.seata.common.util.CompressUtil;
import io.seata.core.exception.TransactionException;
import io.seata.core.model.BranchStatus;
import io.seata.core.model.BranchType;
-import io.seata.server.lock.LockerFactory;
+import io.seata.server.lock.LockManagerFactory;
import io.seata.server.store.SessionStorable;
import io.seata.server.store.StoreConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
/**
* The type Branch session.
*
@@ -45,8 +45,6 @@ public class BranchSession implements Lockable, Comparable, Sessi
private static ThreadLocal byteBufferThreadLocal = ThreadLocal.withInitial(() -> ByteBuffer.allocate(
MAX_BRANCH_SESSION_SIZE));
- private String xid;
-
private long transactionId;
private long branchId;
@@ -66,7 +64,7 @@ public class BranchSession implements Lockable, Comparable, Sessi
private String applicationData;
private ConcurrentHashMap, Set> lockHolder
- = new ConcurrentHashMap<>();
+ = new ConcurrentHashMap, Set>();
/**
* Gets application data.
@@ -190,7 +188,7 @@ public BranchStatus getStatus() {
*
* @param status the status
*/
- public void setStatus(BranchStatus status) {
+ void setStatus(BranchStatus status) {
this.status = status;
}
@@ -230,24 +228,6 @@ public void setBranchId(long branchId) {
this.branchId = branchId;
}
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
@Override
public String toString() {
return "BR:" + branchId + "/" + transactionId;
@@ -269,12 +249,12 @@ public ConcurrentHashMap, Set> getLockHolder() {
@Override
public boolean lock() throws TransactionException {
- return LockerFactory.getLockManager().acquireLock(this);
+ return LockManagerFactory.get().acquireLock(this);
}
@Override
public boolean unlock() throws TransactionException {
- return LockerFactory.getLockManager().releaseLock(this);
+ return LockManagerFactory.get().releaseLock(this);
}
@Override
@@ -288,9 +268,7 @@ public byte[] encode() {
byte[] applicationDataBytes = applicationData != null ? applicationData.getBytes() : null;
- byte[] xidBytes = xid != null ? xid.getBytes() : null;
-
- int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes, xidBytes);
+ int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes);
if (size > MAX_BRANCH_SESSION_SIZE) {
if (lockKeyBytes == null) {
@@ -349,13 +327,6 @@ public byte[] encode() {
byteBuffer.putInt(0);
}
- if(xidBytes != null){
- byteBuffer.putInt(xidBytes.length);
- byteBuffer.put(xidBytes);
- }else {
- byteBuffer.putInt(0);
- }
-
byteBuffer.put((byte)status.getCode());
byteBuffer.flip();
byte[] result = new byte[byteBuffer.limit()];
@@ -364,19 +335,18 @@ public byte[] encode() {
}
private int calBranchSessionSize(byte[] resourceIdBytes, byte[] lockKeyBytes, byte[] clientIdBytes,
- byte[] applicationDataBytes, byte[] xidBytes) {
+ byte[] applicationDataBytes) {
final int size = 8 // trascationId
- + 8 // branchId
- + 4 // resourceIdBytes.length
- + 4 // lockKeyBytes.length
- + 2 // clientIdBytes.length
- + 4 // applicationDataBytes.length
- + 1 // statusCode
- + (resourceIdBytes == null ? 0 : resourceIdBytes.length)
- + (lockKeyBytes == null ? 0 : lockKeyBytes.length)
- + (clientIdBytes == null ? 0 : clientIdBytes.length)
- + (applicationDataBytes == null ? 0 : applicationDataBytes.length)
- + (xidBytes == null ? 0 : xidBytes.length);
+ + 8 // branchId
+ + 4 // resourceIdBytes.length
+ + 4 // lockKeyBytes.length
+ + 2 // clientIdBytes.length
+ + 4 // applicationDataBytes.length
+ + 1 // statusCode
+ + (resourceIdBytes == null ? 0 : resourceIdBytes.length)
+ + (lockKeyBytes == null ? 0 : lockKeyBytes.length)
+ + (clientIdBytes == null ? 0 : clientIdBytes.length)
+ + (applicationDataBytes == null ? 0 : applicationDataBytes.length);
return size;
}
@@ -399,7 +369,7 @@ public void decode(byte[] a) {
try {
this.lockKey = new String(CompressUtil.uncompress(byLockKey));
} catch (IOException e) {
- throw new RuntimeException("decompress lockKey error", e);
+ throw new RuntimeException("uncompress lockKey error", e);
}
} else {
this.lockKey = new String(byLockKey);
@@ -418,12 +388,6 @@ public void decode(byte[] a) {
byteBuffer.get(byApplicationData);
this.applicationData = new String(byApplicationData);
}
- int xidLen = byteBuffer.getInt();
- if (xidLen > 0) {
- byte[] xidBytes = new byte[xidLen];
- byteBuffer.get(xidBytes);
- this.xid = new String(xidBytes);
- }
this.status = BranchStatus.get(byteBuffer.get());
}
diff --git a/server/src/main/java/io/seata/server/session/DefaultSessionManager.java b/server/src/main/java/io/seata/server/session/DefaultSessionManager.java
index a9fcf0cae66..ff24f7f6bba 100644
--- a/server/src/main/java/io/seata/server/session/DefaultSessionManager.java
+++ b/server/src/main/java/io/seata/server/session/DefaultSessionManager.java
@@ -15,30 +15,19 @@
*/
package io.seata.server.session;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import io.seata.common.loader.LoadLevel;
-import io.seata.core.exception.TransactionException;
-import io.seata.server.store.AbstractTransactionStoreManager;
import io.seata.server.store.SessionStorable;
+import io.seata.server.store.TransactionStoreManager;
+import io.seata.server.store.TransactionWriteStore;
/**
- * The type Default session manager, store session data in memory.
+ * The type Default session manager.
*
* @author sharajava
*/
-@LoadLevel(name = "default")
public class DefaultSessionManager extends AbstractSessionManager {
- /**
- * The Session map.
- */
- protected Map sessionMap = new ConcurrentHashMap();
-
/**
* Instantiates a new Default session manager.
*
@@ -46,45 +35,27 @@ public class DefaultSessionManager extends AbstractSessionManager {
*/
public DefaultSessionManager(String name) {
super(name);
- transactionStoreManager = new AbstractTransactionStoreManager() {
+ transactionStoreManager = new TransactionStoreManager() {
@Override
public boolean writeSession(LogOperation logOperation, SessionStorable session) {
return true;
}
- };
- }
- @Override
- public void addGlobalSession(GlobalSession session) throws TransactionException {
- super.addGlobalSession(session);
- sessionMap.put(session.getXid(), session);
- }
-
- @Override
- public GlobalSession findGlobalSession(String xid) {
- return sessionMap.get(xid);
- }
+ @Override
+ public void shutdown() {
- @Override
- public void removeGlobalSession(GlobalSession session) throws TransactionException {
- super.removeGlobalSession(session);
- sessionMap.remove(session.getXid());
- }
+ }
- @Override
- public Collection allSessions() {
- return sessionMap.values();
- }
+ @Override
+ public List readWriteStoreFromFile(int readSize, boolean isHistory) {
+ return null;
+ }
- @Override
- public List findGlobalSessions(SessionCondition condition) {
- List found = new ArrayList<>();
- for (GlobalSession globalSession : sessionMap.values()) {
- if (System.currentTimeMillis() - globalSession.getBeginTime() > condition.getOverTimeAliveMills()) {
- found.add(globalSession);
+ @Override
+ public boolean hasRemaining(boolean isHistory) {
+ return false;
}
- }
- return found;
+ };
}
@Override
diff --git a/server/src/main/java/io/seata/server/session/file/FileBasedSessionManager.java b/server/src/main/java/io/seata/server/session/FileBasedSessionManager.java
similarity index 71%
rename from server/src/main/java/io/seata/server/session/file/FileBasedSessionManager.java
rename to server/src/main/java/io/seata/server/session/FileBasedSessionManager.java
index 02ade24cefb..1684cccdfac 100644
--- a/server/src/main/java/io/seata/server/session/file/FileBasedSessionManager.java
+++ b/server/src/main/java/io/seata/server/session/FileBasedSessionManager.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.seata.server.session.file;
+package io.seata.server.session;
import java.io.File;
import java.io.IOException;
@@ -23,31 +23,21 @@
import java.util.Map;
import io.seata.common.exception.ShouldNeverHappenException;
-import io.seata.common.loader.EnhancedServiceLoader;
-import io.seata.common.loader.LoadLevel;
import io.seata.config.ConfigurationFactory;
import io.seata.core.constants.ConfigurationKeys;
import io.seata.core.model.GlobalStatus;
-import io.seata.core.store.StoreMode;
-import io.seata.server.session.BranchSession;
-import io.seata.server.session.DefaultSessionManager;
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.Reloadable;
-import io.seata.server.session.SessionManager;
-import io.seata.server.store.ReloadableStore;
import io.seata.server.UUIDGenerator;
+import io.seata.server.store.FileTransactionStoreManager;
import io.seata.server.store.SessionStorable;
import io.seata.server.store.TransactionStoreManager;
import io.seata.server.store.TransactionWriteStore;
-
/**
* The type File based session manager.
*
* @author jimin.jm @alibaba-inc.com
*/
-@LoadLevel(name = "file")
-public class FileBasedSessionManager extends DefaultSessionManager implements Reloadable {
+public class FileBasedSessionManager extends AbstractSessionManager implements Reloadable {
private static final int READ_SIZE = ConfigurationFactory.getInstance().getInt(
ConfigurationKeys.SERVICE_SESSION_RELOAD_READ_SIZE, 100);
@@ -61,9 +51,7 @@ public class FileBasedSessionManager extends DefaultSessionManager implements Re
*/
public FileBasedSessionManager(String name, String sessionStoreFilePath) throws IOException {
super(name);
- transactionStoreManager = EnhancedServiceLoader.load(TransactionStoreManager.class, StoreMode.FILE.name(),
- new Class[]{String.class, SessionManager.class},
- new Object[]{sessionStoreFilePath + File.separator + name, this});
+ transactionStoreManager = new FileTransactionStoreManager(sessionStoreFilePath + File.separator + name, this);
}
@Override
@@ -80,13 +68,13 @@ private void restoreSessions() {
if (!unhandledBranchBuffer.isEmpty()) {
unhandledBranchBuffer.values().forEach(branchSession -> {
- String xid = branchSession.getXid();
+ long tid = branchSession.getTransactionId();
long bid = branchSession.getBranchId();
- GlobalSession found = sessionMap.get(xid);
+ GlobalSession found = sessionMap.get(tid);
if (found == null) {
// Ignore
if (LOGGER.isInfoEnabled()) {
- LOGGER.info("GlobalSession Does Not Exists For BranchSession [" + bid + "/" + xid + "]");
+ LOGGER.info("GlobalSession Does Not Exists For BranchSession [" + bid + "/" + tid + "]");
}
} else {
BranchSession existingBranch = found.getBranch(branchSession.getBranchId());
@@ -103,7 +91,7 @@ private void restoreSessions() {
private void washSessions() {
if (sessionMap.size() > 0) {
- Iterator> iterator = sessionMap.entrySet().iterator();
+ Iterator> iterator = sessionMap.entrySet().iterator();
while (iterator.hasNext()) {
GlobalSession globalSession = iterator.next().getValue();
@@ -128,11 +116,8 @@ private void washSessions() {
}
private void restoreSessions(boolean isHistory, Map unhandledBranchBuffer) {
- if(!(transactionStoreManager instanceof ReloadableStore)){
- return;
- }
- while (((ReloadableStore)transactionStoreManager).hasRemaining(isHistory)) {
- List stores = ((ReloadableStore)transactionStoreManager).readWriteStore(READ_SIZE, isHistory);
+ while (transactionStoreManager.hasRemaining(isHistory)) {
+ List stores = transactionStoreManager.readWriteStoreFromFile(READ_SIZE, isHistory);
restore(stores, unhandledBranchBuffer);
}
}
@@ -146,40 +131,31 @@ private void restore(List stores, Map stores, Map byteBufferThreadLocal = ThreadLocal.withInitial(() -> ByteBuffer.allocate(
MAX_GLOBAL_SESSION_SIZE));
- private String xid;
-
private long transactionId;
private volatile GlobalStatus status;
@@ -64,9 +61,7 @@ public class GlobalSession implements SessionLifecycle, SessionStorable {
private long beginTime;
- private String applicationData;
-
- private boolean active = true;
+ private boolean active;
private ArrayList branchSessions = new ArrayList<>();
@@ -170,7 +165,7 @@ public void end() throws TransactionException {
}
- public void clean() throws TransactionException {
+ private void clean() throws TransactionException {
for (BranchSession branchSession : branchSessions) {
branchSession.unlock();
}
@@ -287,7 +282,6 @@ public GlobalSession(String applicationId, String transactionServiceGroup, Strin
this.transactionServiceGroup = transactionServiceGroup;
this.transactionName = transactionName;
this.timeout = timeout;
- this.xid = XID.generateXID(transactionId);
}
/**
@@ -299,15 +293,6 @@ public long getTransactionId() {
return transactionId;
}
- /**
- * Sets transaction id.
- *
- * @param transactionId the transaction id
- */
- public void setTransactionId(long transactionId) {
- this.transactionId = transactionId;
- }
-
/**
* Gets status.
*
@@ -322,28 +307,10 @@ public GlobalStatus getStatus() {
*
* @param status the status
*/
- public void setStatus(GlobalStatus status) {
+ void setStatus(GlobalStatus status) {
this.status = status;
}
- /**
- * Gets xid.
- *
- * @return the xid
- */
- public String getXid() {
- return xid;
- }
-
- /**
- * Sets xid.
- *
- * @param xid the xid
- */
- public void setXid(String xid) {
- this.xid = xid;
- }
-
/**
* Gets application id.
*
@@ -389,32 +356,6 @@ public long getBeginTime() {
return beginTime;
}
- /**
- * Sets begin time.
- *
- * @param beginTime the begin time
- */
- public void setBeginTime(long beginTime) {
- this.beginTime = beginTime;
- }
-
- /**
- * Gets application data.
- *
- * @return the application data
- */
- public String getApplicationData() {
- return applicationData;
- }
-
- /**
- * Sets application data.
- *
- * @param applicationData the application data
- */
- public void setApplicationData(String applicationData) {
- this.applicationData = applicationData;
- }
/**
* Create global session global session.
@@ -449,11 +390,7 @@ public byte[] encode() {
byte[] byTxNameBytes = transactionName != null ? transactionName.getBytes() : null;
- byte[] xidBytes = xid != null ? xid.getBytes():null;
-
- byte[] applicationDataBytes = applicationData != null ? applicationData.getBytes():null;
-
- int size = calGlobalSessionSize(byApplicationIdBytes, byServiceGroupBytes, byTxNameBytes, xidBytes, applicationDataBytes);
+ int size = calGlobalSessionSize(byApplicationIdBytes, byServiceGroupBytes, byTxNameBytes);
if (size > MAX_GLOBAL_SESSION_SIZE) {
throw new RuntimeException("global session size exceeded, size : " + size + " maxBranchSessionSize : " +
@@ -483,19 +420,6 @@ public byte[] encode() {
} else {
byteBuffer.putShort((short)0);
}
- if(xidBytes != null){
- byteBuffer.putInt(xidBytes.length);
- byteBuffer.put(xidBytes);
- }else {
- byteBuffer.putInt(0);
- }
- if(applicationDataBytes != null){
- byteBuffer.putInt(applicationDataBytes.length);
- byteBuffer.put(applicationDataBytes);
- }else {
- byteBuffer.putInt(0);
- }
-
byteBuffer.putLong(beginTime);
byteBuffer.put((byte)status.getCode());
byteBuffer.flip();
@@ -504,20 +428,17 @@ public byte[] encode() {
return result;
}
- private int calGlobalSessionSize(byte[] byApplicationIdBytes, byte[] byServiceGroupBytes, byte[] byTxNameBytes,
- byte[] xidBytes, byte[] applicationDataBytes) {
+ private int calGlobalSessionSize(byte[] byApplicationIdBytes, byte[] byServiceGroupBytes, byte[] byTxNameBytes) {
final int size = 8 // trascationId
- + 4 // timeout
- + 2 // byApplicationIdBytes.length
- + 2 // byServiceGroupBytes.length
- + 2 // byTxNameBytes.length
- + 8 // beginTime
- + 1 // statusCode
- + (byApplicationIdBytes == null ? 0 : byApplicationIdBytes.length)
- + (byServiceGroupBytes == null ? 0 : byServiceGroupBytes.length)
- + (byTxNameBytes == null ? 0 : byTxNameBytes.length)
- + (xidBytes ==null ? 0 : xidBytes.length)
- + (applicationDataBytes == null ? 0 : applicationDataBytes.length);
+ + 4 // timeout
+ + 2 // byApplicationIdBytes.length
+ + 2 // byServiceGroupBytes.length
+ + 2 // byTxNameBytes.length
+ + 8 // beginTime
+ + 1 // statusCode
+ + (byApplicationIdBytes == null ? 0 : byApplicationIdBytes.length)
+ + (byServiceGroupBytes == null ? 0 : byServiceGroupBytes.length)
+ + (byTxNameBytes == null ? 0 : byTxNameBytes.length);
return size;
}
@@ -544,19 +465,6 @@ public void decode(byte[] a) {
byteBuffer.get(byTxName);
this.transactionName = new String(byTxName);
}
- int xidLen = byteBuffer.getInt();
- if(xidLen > 0 ){
- byte[] xidBytes = new byte[xidLen];
- byteBuffer.get(xidBytes);
- this.xid = new String(xidBytes);
- }
- int applicationDataLen = byteBuffer.getInt();
- if(applicationDataLen > 0){
- byte[] applicationDataLenBytes = new byte[applicationDataLen];
- byteBuffer.get(applicationDataLenBytes);
- this.applicationData = new String(applicationDataLenBytes);
- }
-
this.beginTime = byteBuffer.getLong();
this.status = GlobalStatus.get(byteBuffer.get());
}
diff --git a/server/src/main/java/io/seata/server/session/SessionCondition.java b/server/src/main/java/io/seata/server/session/SessionCondition.java
index 1b192bb0c85..4063d7aa378 100644
--- a/server/src/main/java/io/seata/server/session/SessionCondition.java
+++ b/server/src/main/java/io/seata/server/session/SessionCondition.java
@@ -15,8 +15,6 @@
*/
package io.seata.server.session;
-import io.seata.core.model.GlobalStatus;
-
/**
* The type Session condition.
*
@@ -24,45 +22,8 @@
* @date 2018 /12/13
*/
public class SessionCondition {
- private Long transactionId;
- private String xid;
- private GlobalStatus status;
- private GlobalStatus[] statuses;
- private long overTimeAliveMills;
-
- /**
- * Instantiates a new Session condition.
- */
- public SessionCondition() {
- }
- /**
- * Instantiates a new Session condition.
- *
- * @param xid the xid
- */
- public SessionCondition(String xid) {
- this.xid = xid;
- }
-
- /**
- * Instantiates a new Session condition.
- *
- * @param status the status
- */
- public SessionCondition(GlobalStatus status) {
- this.status = status;
- statuses = new GlobalStatus[]{status};
- }
-
- /**
- * Instantiates a new Session condition.
- *
- * @param statuses the statuses
- */
- public SessionCondition(GlobalStatus[] statuses) {
- this.statuses = statuses;
- }
+ private long overTimeAliveMills;
/**
* Instantiates a new Session condition.
@@ -73,23 +34,6 @@ public SessionCondition( long overTimeAliveMills) {
this.overTimeAliveMills = overTimeAliveMills;
}
- /**
- * Gets status.
- *
- * @return the status
- */
- public GlobalStatus getStatus() {
- return status;
- }
-
- /**
- * Sets status.
- *
- * @param status the status
- */
- public void setStatus(GlobalStatus status) {
- this.status = status;
- }
/**
* Gets over time alive mills.
@@ -108,28 +52,4 @@ public long getOverTimeAliveMills() {
public void setOverTimeAliveMills(long overTimeAliveMills) {
this.overTimeAliveMills = overTimeAliveMills;
}
-
- public Long getTransactionId() {
- return transactionId;
- }
-
- public void setTransactionId(Long transactionId) {
- this.transactionId = transactionId;
- }
-
- public String getXid() {
- return xid;
- }
-
- public void setXid(String xid) {
- this.xid = xid;
- }
-
- public GlobalStatus[] getStatuses() {
- return statuses;
- }
-
- public void setStatuses(GlobalStatus[] statuses) {
- this.statuses = statuses;
- }
}
diff --git a/server/src/main/java/io/seata/server/session/SessionHelper.java b/server/src/main/java/io/seata/server/session/SessionHelper.java
index fec302b1535..b3295d24e8f 100644
--- a/server/src/main/java/io/seata/server/session/SessionHelper.java
+++ b/server/src/main/java/io/seata/server/session/SessionHelper.java
@@ -47,7 +47,6 @@ public static BranchSession newBranchByGlobal(GlobalSession globalSession, Branc
String applicationData, String lockKeys, String clientId) {
BranchSession branchSession = new BranchSession();
- branchSession.setXid(globalSession.getXid());
branchSession.setTransactionId(globalSession.getTransactionId());
branchSession.setBranchId(UUIDGenerator.generateUUID());
branchSession.setBranchType(branchType);
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 316b6e11d99..30f4b4d00b3 100644
--- a/server/src/main/java/io/seata/server/session/SessionHolder.java
+++ b/server/src/main/java/io/seata/server/session/SessionHolder.java
@@ -21,7 +21,6 @@
import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.common.exception.StoreException;
-import io.seata.common.loader.EnhancedServiceLoader;
import io.seata.common.util.StringUtils;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
@@ -47,11 +46,6 @@ public class SessionHolder {
*/
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
- /**
- * The constant DEFAULT.
- */
- public static final String DEFAULT = "default";
-
/**
* The constant ROOT_SESSION_MANAGER_NAME.
*/
@@ -88,33 +82,23 @@ public static void init(String mode) throws IOException {
//the store mode
StoreMode storeMode = StoreMode.valueof(mode);
if (StoreMode.DB.equals(storeMode)) {
- //database store
- 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});;
+ //TODO database store
+
} else if (StoreMode.FILE.equals(storeMode)) {
//file store
String sessionStorePath = CONFIG.getConfig(ConfigurationKeys.STORE_FILE_DIR);
if (sessionStorePath == null) {
throw new StoreException("the {store.file.dir} is empty.");
}
- ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, StoreMode.FILE.name(), 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});;
+ ROOT_SESSION_MANAGER = new FileBasedSessionManager(ROOT_SESSION_MANAGER_NAME, sessionStorePath);
+ ASYNC_COMMITTING_SESSION_MANAGER = new DefaultSessionManager(ASYNC_COMMITTING_SESSION_MANAGER_NAME);
+ RETRY_COMMITTING_SESSION_MANAGER = new DefaultSessionManager(RETRY_COMMITTING_SESSION_MANAGER_NAME);
+ RETRY_ROLLBACKING_SESSION_MANAGER = new DefaultSessionManager(RETRY_ROLLBACKING_SESSION_MANAGER_NAME);
} else {
//unknown store
throw new IllegalArgumentException("unknown store mode:" + mode);
}
- //relaod
- reload();
- }
- /**
- * Reload.
- */
- protected static void reload(){
if (ROOT_SESSION_MANAGER instanceof Reloadable) {
((Reloadable) ROOT_SESSION_MANAGER).reload();
@@ -189,6 +173,7 @@ protected static void reload(){
});
}
}
+
}
/**
@@ -242,11 +227,11 @@ public static final SessionManager getRetryRollbackingSessionManager() {
/**
* Find global session.
*
- * @param xid the xid
+ * @param transactionId the transaction id
* @return the global session
*/
- public static GlobalSession findGlobalSession(String xid) {
- return getRootSessionManager().findGlobalSession(xid);
+ public static GlobalSession findGlobalSession(Long transactionId) {
+ return getRootSessionManager().findGlobalSession(transactionId);
}
public static void destory() {
diff --git a/server/src/main/java/io/seata/server/session/SessionManager.java b/server/src/main/java/io/seata/server/session/SessionManager.java
index e7e94017191..2883d440482 100644
--- a/server/src/main/java/io/seata/server/session/SessionManager.java
+++ b/server/src/main/java/io/seata/server/session/SessionManager.java
@@ -41,10 +41,11 @@ public interface SessionManager extends SessionLifecycleListener, Disposable {
/**
* Find global session global session.
*
- * @param xid the xid
+ * @param transactionId the transaction id
* @return the global session
+ * @throws TransactionException the transaction exception
*/
- GlobalSession findGlobalSession(String xid) ;
+ GlobalSession findGlobalSession(Long transactionId);
/**
* Update global session status.
diff --git a/server/src/main/java/io/seata/server/session/db/DataBaseSessionManager.java b/server/src/main/java/io/seata/server/session/db/DataBaseSessionManager.java
deleted file mode 100644
index 333b78e3ba1..00000000000
--- a/server/src/main/java/io/seata/server/session/db/DataBaseSessionManager.java
+++ /dev/null
@@ -1,186 +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.server.session.db;
-
-import io.seata.common.exception.StoreException;
-import io.seata.common.executor.Initialize;
-import io.seata.common.loader.EnhancedServiceLoader;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.StringUtils;
-import io.seata.core.exception.TransactionException;
-import io.seata.core.model.BranchStatus;
-import io.seata.core.model.GlobalStatus;
-import io.seata.core.store.StoreMode;
-import io.seata.server.session.AbstractSessionManager;
-import io.seata.server.session.BranchSession;
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.SessionCondition;
-import io.seata.server.session.SessionHolder;
-import io.seata.server.session.SessionLifecycleListener;
-import io.seata.server.session.SessionManager;
-import io.seata.server.store.TransactionStoreManager;
-import io.seata.server.store.TransactionStoreManager.LogOperation;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * The Data base session manager.
- *
- * @author zhangsen
- * @data 2019 /4/4
- */
-@LoadLevel(name = "db")
-public class DataBaseSessionManager extends AbstractSessionManager implements SessionManager, SessionLifecycleListener, Initialize {
-
- /**
- * The constant LOGGER.
- */
- protected static final Logger LOGGER = LoggerFactory.getLogger(DataBaseSessionManager.class);
-
- /**
- * The Task name.
- */
- protected String taskName;
-
- /**
- * Instantiates a new Data base session manager.
- */
- public DataBaseSessionManager() {
- super();
- }
-
- /**
- * Instantiates a new Data base session manager.
- *
- * @param name the name
- */
- public DataBaseSessionManager(String name) {
- super();
- this.taskName = name;
- }
-
- @Override
- public void init() {
- transactionStoreManager = EnhancedServiceLoader.load(TransactionStoreManager.class, StoreMode.DB.name());
- }
-
- @Override
- public void addGlobalSession(GlobalSession session) throws TransactionException {
- if (StringUtils.isBlank(taskName)) {
- boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);
- if (!ret) {
- throw new StoreException("addGlobalSession failed.");
- }
- }else {
- boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
- if (!ret) {
- throw new StoreException("addGlobalSession failed.");
- }
- }
- }
-
- @Override
- public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
- if (StringUtils.isNotBlank(taskName)) {
- return;
- }
- session.setStatus(status);
- boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
- if (!ret) {
- throw new StoreException("updateGlobalSessionStatus failed.");
- }
- }
-
- @Override
- public void removeGlobalSession(GlobalSession session) throws TransactionException {
- if (StringUtils.isNotBlank(taskName)) {
- return;
- }
- boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);
- if (!ret) {
- throw new StoreException("removeGlobalSession failed.");
- }
- }
-
- @Override
- public void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
- if (StringUtils.isNotBlank(taskName)) {
- return;
- }
- boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_ADD, session);
- if (!ret) {
- throw new StoreException("addBranchSession failed.");
- }
- }
-
- @Override
- public void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException {
- if (StringUtils.isNotBlank(taskName)) {
- return;
- }
- boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_UPDATE, session);
- if (!ret) {
- throw new StoreException("updateBranchSessionStatus failed.");
- }
- }
-
- @Override
- public void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
- if (StringUtils.isNotBlank(taskName)) {
- return;
- }
- boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_REMOVE, session);
- if (!ret) {
- throw new StoreException("removeBranchSession failed.");
- }
- }
-
- @Override
- public GlobalSession findGlobalSession(String xid) {
- return transactionStoreManager.readSession(xid);
- }
-
- @Override
- public Collection allSessions() {
- //get by taskName
- if (SessionHolder.ASYNC_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
- return findGlobalSessions(new SessionCondition(GlobalStatus.AsyncCommitting));
- } else if (SessionHolder.RETRY_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
- return findGlobalSessions(new SessionCondition(new GlobalStatus[]{GlobalStatus.CommitRetrying}));
- } else if (SessionHolder.RETRY_ROLLBACKING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
- return findGlobalSessions(new SessionCondition(new GlobalStatus[]{GlobalStatus.RollbackRetrying,
- GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying}));
- } else {
- //all data
- return findGlobalSessions(new SessionCondition(new GlobalStatus[]{
- GlobalStatus.UnKnown, GlobalStatus.Begin,
- GlobalStatus.Committing, GlobalStatus.CommitRetrying, GlobalStatus.Rollbacking, GlobalStatus.RollbackRetrying,
- GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.AsyncCommitting}));
- }
- }
-
- @Override
- public List findGlobalSessions(SessionCondition condition) {
- //nothing need to do
- return transactionStoreManager.readSession(condition);
- }
-
-
-
-}
\ No newline at end of file
diff --git a/server/src/main/java/io/seata/server/store/AbstractTransactionStoreManager.java b/server/src/main/java/io/seata/server/store/AbstractTransactionStoreManager.java
deleted file mode 100644
index f024bd772bf..00000000000
--- a/server/src/main/java/io/seata/server/store/AbstractTransactionStoreManager.java
+++ /dev/null
@@ -1,44 +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.server.store;
-
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.SessionCondition;
-
-import java.util.List;
-
-/**
- * The type Abstract transaction store manager.
- *
- * @author zhangsen
- * @data 2019 /4/25
- */
-public abstract class AbstractTransactionStoreManager implements TransactionStoreManager {
-
- @Override
- public GlobalSession readSession(String xid) {
- return null;
- }
-
- @Override
- public List readSession(SessionCondition sessionCondition) {
- return null;
- }
-
- @Override
- public void shutdown() {
- }
-}
diff --git a/server/src/main/java/io/seata/server/store/file/FileTransactionStoreManager.java b/server/src/main/java/io/seata/server/store/FileTransactionStoreManager.java
similarity index 92%
rename from server/src/main/java/io/seata/server/store/file/FileTransactionStoreManager.java
rename to server/src/main/java/io/seata/server/store/FileTransactionStoreManager.java
index 5f8e42d8a31..9b3a32229c5 100644
--- a/server/src/main/java/io/seata/server/store/file/FileTransactionStoreManager.java
+++ b/server/src/main/java/io/seata/server/store/FileTransactionStoreManager.java
@@ -13,7 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.seata.server.store.file;
+package io.seata.server.store;
+
+import io.seata.common.thread.NamedThreadFactory;
+import io.seata.common.util.CollectionUtils;
+import io.seata.server.session.BranchSession;
+import io.seata.server.session.GlobalSession;
+import io.seata.server.session.SessionCondition;
+import io.seata.server.session.SessionManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
@@ -24,39 +33,17 @@
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantLock;
-import io.seata.common.exception.StoreException;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.thread.NamedThreadFactory;
-import io.seata.common.util.CollectionUtils;
-import io.seata.server.session.BranchSession;
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.SessionCondition;
-import io.seata.server.session.SessionManager;
-import io.seata.server.store.AbstractTransactionStoreManager;
-import io.seata.server.store.FlushDiskMode;
-import io.seata.server.store.ReloadableStore;
-import io.seata.server.store.SessionStorable;
-import io.seata.server.store.StoreConfig;
-import io.seata.server.store.TransactionStoreManager;
-import io.seata.server.store.TransactionWriteStore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* The type File transaction store manager.
*
* @author jimin.jm @alibaba-inc.com
*/
-@LoadLevel(name = "file")
-public class FileTransactionStoreManager extends AbstractTransactionStoreManager implements TransactionStoreManager, ReloadableStore {
+public class FileTransactionStoreManager implements TransactionStoreManager {
+
private static final Logger LOGGER = LoggerFactory.getLogger(FileTransactionStoreManager.class);
private static final int MAX_THREAD_WRITE = 1;
@@ -132,7 +119,8 @@ public class FileTransactionStoreManager extends AbstractTransactionStoreManager
*/
public FileTransactionStoreManager(String fullFileName, SessionManager sessionManager) throws IOException {
initFile(fullFileName);
- fileWriteExecutor = new ThreadPoolExecutor(MAX_THREAD_WRITE, MAX_THREAD_WRITE, Integer.MAX_VALUE, TimeUnit.MILLISECONDS,
+ fileWriteExecutor =
+ new ThreadPoolExecutor(MAX_THREAD_WRITE, MAX_THREAD_WRITE, Integer.MAX_VALUE, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(),
new NamedThreadFactory("fileTransactionStore", MAX_THREAD_WRITE, true));
writeDataFileRunnable = new WriteDataFileRunnable();
@@ -259,16 +247,6 @@ private boolean findTimeoutAndSave() throws IOException {
return false;
}
- @Override
- public GlobalSession readSession(String xid) {
- throw new StoreException("unsupport for read from file, xid:" + xid);
- }
-
- @Override
- public List readSession(SessionCondition sessionCondition) {
- throw new StoreException("unsupport for read from file");
- }
-
@Override
public void shutdown() {
if (null != fileWriteExecutor) {
@@ -279,7 +257,7 @@ public void shutdown() {
++retry;
try {
Thread.sleep(SHUTDOWN_CHECK_INTERNAL);
- } catch (InterruptedException ignore) {
+ } catch (InterruptedException exx) {
}
}
if (retry >= MAX_SHUTDOWN_RETRY) {
@@ -295,7 +273,7 @@ public void shutdown() {
}
@Override
- public List readWriteStore(int readSize, boolean isHistory) {
+ public List readWriteStoreFromFile(int readSize, boolean isHistory) {
File file = null;
long currentOffset = 0;
if (isHistory) {
@@ -327,7 +305,7 @@ public boolean hasRemaining(boolean isHistory) {
raf = new RandomAccessFile(file, "r");
return currentOffset < raf.length();
- } catch (IOException ignore) {
+ } catch (IOException exx) {
} finally {
closeFile(raf);
}
@@ -534,7 +512,7 @@ public void run() {
StoreRequest storeRequest = storeRequests.poll(MAX_WAIT_TIME_MILLS, TimeUnit.MILLISECONDS);
handleStoreRequest(storeRequest);
} catch (Exception exx) {
- LOGGER.error("write file error: {}", exx.getMessage(), exx);
+ LOGGER.error("write file error", exx.getMessage());
}
}
handleRestRequest();
diff --git a/server/src/main/java/io/seata/server/store/TransactionStoreManager.java b/server/src/main/java/io/seata/server/store/TransactionStoreManager.java
index 26dc122009c..da7d44a4ad9 100644
--- a/server/src/main/java/io/seata/server/store/TransactionStoreManager.java
+++ b/server/src/main/java/io/seata/server/store/TransactionStoreManager.java
@@ -15,9 +15,6 @@
*/
package io.seata.server.store;
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.SessionCondition;
-
import java.util.List;
/**
@@ -36,28 +33,27 @@ public interface TransactionStoreManager {
*/
boolean writeSession(LogOperation logOperation, SessionStorable session);
-
/**
- * Read global session global session.
- *
- * @param xid the xid
- * @return the global session
+ * Shutdown.
*/
- GlobalSession readSession(String xid);
+ void shutdown();
/**
- * Read session by status list.
+ * Read write store from file list.
*
- * @param sessionCondition the session condition
+ * @param readSize the read size
+ * @param isHistory the is history
* @return the list
*/
- List readSession(SessionCondition sessionCondition);
+ List readWriteStoreFromFile(int readSize, boolean isHistory);
/**
- * Shutdown.
+ * Has remaining boolean.
+ *
+ * @param isHistory the is history
+ * @return the boolean
*/
- void shutdown();
-
+ boolean hasRemaining(boolean isHistory);
/**
* The enum Log operation.
diff --git a/server/src/main/java/io/seata/server/store/db/DatabaseTransactionStoreManager.java b/server/src/main/java/io/seata/server/store/db/DatabaseTransactionStoreManager.java
deleted file mode 100644
index 1cce734f8ea..00000000000
--- a/server/src/main/java/io/seata/server/store/db/DatabaseTransactionStoreManager.java
+++ /dev/null
@@ -1,299 +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.server.store.db;
-
-
-import io.seata.common.exception.StoreException;
-import io.seata.common.executor.Initialize;
-import io.seata.common.loader.EnhancedServiceLoader;
-import io.seata.common.loader.LoadLevel;
-import io.seata.common.util.CollectionUtils;
-import io.seata.common.util.StringUtils;
-import io.seata.config.Configuration;
-import io.seata.config.ConfigurationFactory;
-import io.seata.core.constants.ConfigurationKeys;
-import io.seata.core.model.BranchStatus;
-import io.seata.core.model.BranchType;
-import io.seata.core.model.GlobalStatus;
-import io.seata.core.store.BranchTransactionDO;
-import io.seata.core.store.GlobalTransactionDO;
-import io.seata.core.store.LogStore;
-import io.seata.core.store.StoreMode;
-import io.seata.core.store.db.DataSourceGenerator;
-import io.seata.server.session.BranchSession;
-import io.seata.server.session.GlobalSession;
-import io.seata.server.session.SessionCondition;
-import io.seata.server.store.AbstractTransactionStoreManager;
-import io.seata.server.store.SessionStorable;
-import io.seata.server.store.TransactionStoreManager;
-
-import javax.sql.DataSource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * The type Database transaction store manager.
- *
- * @author zhangsen
- * @data 2019 /4/2
- */
-@LoadLevel(name = "db")
-public class DatabaseTransactionStoreManager extends AbstractTransactionStoreManager implements TransactionStoreManager, Initialize {
-
- /**
- * The constant CONFIG.
- */
- protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
-
- /**
- * The constant DEFAULT_LOG_QUERY_LIMIT.
- */
- protected static final int DEFAULT_LOG_QUERY_LIMIT = 100;
-
- /**
- * is inited
- */
- protected AtomicBoolean inited = new AtomicBoolean(false);
-
- /**
- * The Log store.
- */
- protected LogStore logStore ;
-
-
- /**
- * The Log query limit.
- */
- protected int logQueryLimit ;
-
- /**
- * Instantiates a new Database transaction store manager.
- */
- public DatabaseTransactionStoreManager(){
- }
-
- @Override
- public synchronized void init(){
- if(inited.get()){
- return ;
- }
- logQueryLimit = CONFIG.getInt(ConfigurationKeys.STORE_DB_LOG_QUERY_LIMIT, DEFAULT_LOG_QUERY_LIMIT);
- String datasourceType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
- //init dataSource
- DataSourceGenerator dataSourceGenerator = EnhancedServiceLoader.load(DataSourceGenerator.class, datasourceType);
- DataSource logStoreDataSource = dataSourceGenerator.generateDataSource();
- logStore = EnhancedServiceLoader.load(LogStore.class, StoreMode.DB.name(), new Class[]{DataSource.class}, new Object[]{logStoreDataSource});
- inited.set(true);
- }
-
- @Override
- public boolean writeSession(LogOperation logOperation, SessionStorable session) {
- if (LogOperation.GLOBAL_ADD.equals(logOperation)){
- logStore.insertGlobalTransactionDO(convertGlobalTransactionDO(session));
- }else if(LogOperation.GLOBAL_UPDATE.equals(logOperation)){
- logStore.updateGlobalTransactionDO(convertGlobalTransactionDO(session));
- }else if(LogOperation.GLOBAL_REMOVE.equals(logOperation)){
- logStore.deleteGlobalTransactionDO(convertGlobalTransactionDO(session));
- }else if(LogOperation.BRANCH_ADD.equals(logOperation)){
- logStore.insertBranchTransactionDO(convertBranchTransactionDO(session));
- }else if(LogOperation.BRANCH_UPDATE.equals(logOperation)){
- logStore.updateBranchTransactionDO(convertBranchTransactionDO(session));
- }else if(LogOperation.BRANCH_REMOVE.equals(logOperation)){
- logStore.deleteBranchTransactionDO(convertBranchTransactionDO(session));
- }else {
- throw new StoreException("Unknown LogOperation:" + logOperation.name());
- }
- return true;
- }
-
- /**
- * Read session global session.
- *
- * @param transactionId the transaction id
- * @return the global session
- */
- public GlobalSession readSession(Long transactionId) {
- //global transaction
- GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(transactionId);
- if(globalTransactionDO == null){
- return null;
- }
- //branch transactions
- List branchTransactionDOs = logStore.queryBranchTransactionDO(globalTransactionDO.getXid());
- return getGlobalSession(globalTransactionDO, branchTransactionDOs);
- }
-
- /**
- * Read session global session.
- *
- * @param xid the xid
- * @return the global session
- */
- @Override
- public GlobalSession readSession(String xid) {
- //global transaction
- GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(xid);
- if(globalTransactionDO == null){
- return null;
- }
- //branch transactions
- List branchTransactionDOs = logStore.queryBranchTransactionDO(globalTransactionDO.getXid());
- return getGlobalSession(globalTransactionDO, branchTransactionDOs);
- }
-
- /**
- * Read session list.
- *
- * @param statuses the statuses
- * @return the list
- */
- public List readSession(GlobalStatus[] statuses) {
- int[] states = new int[statuses.length];
- for(int i = 0; i < statuses.length; i++){
- states[i] = statuses[i].getCode();
- }
- List globalSessions = new ArrayList