mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
删除无用 module ,方便升级
This commit is contained in:
1 parent
5cbee1e4d3
commit
9eeecf0179
545 files changed
+51
-85505
No files matched your search
@@ -1 +0,0 @@
|
||||
java-baseline=8
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server-api</artifactId>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server-biz</artifactId>
|
||||
@@ -62,7 +62,7 @@
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-app-server-api</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</dependency>
|
||||
<!--必备: log 依赖-->
|
||||
<dependency>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-app-server</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-auth</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-audit</artifactId>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<description>pigx 公共版本控制</description>
|
||||
|
||||
<properties>
|
||||
<pigx.version>5.1.0</pigx.version>
|
||||
<pigx.version>5.2.0-snapshot</pigx.version>
|
||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||
<mybatis-plus-join.version>1.4.5</mybatis-plus-join.version>
|
||||
<dynamic-ds.version>3.6.0</dynamic-ds.version>
|
||||
@@ -44,7 +44,6 @@
|
||||
<seata.version>1.6.1</seata.version>
|
||||
<asm.version>7.1</asm.version>
|
||||
<log4j2.version>2.17.1</log4j2.version>
|
||||
<javaformat.plugin.version>0.0.23</javaformat.plugin.version>
|
||||
<docker.plugin.version>0.33.0</docker.plugin.version>
|
||||
<cloud.plugin.version>1.0.0</cloud.plugin.version>
|
||||
<sentinel.version>1.8.4</sentinel.version>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-data</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-encrypt-api</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-excel</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gateway</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-gray</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-idempotent</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-job</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-log</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-oss</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-seata</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-security</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-sequence</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-swagger</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-websocket</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-xss</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-gateway</artifactId>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-register</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms-api</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms-biz</artifactId>
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-upms</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-codegen</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-daemon-elastic-job</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-jimu-platform</artifactId>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-monitor</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-mp-platform</artifactId>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-oa-platform</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-pay-platform</artifactId>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
<version>5.2.0-snapshot</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-report-platform</artifactId>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
FROM pig4cloud/java:8-jre
|
||||
|
||||
MAINTAINER wangiegie@gmail.com
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
ENV JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
|
||||
|
||||
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
RUN mkdir -p /pigx-seata-server
|
||||
|
||||
WORKDIR /pigx-seata-server
|
||||
|
||||
EXPOSE 8091
|
||||
|
||||
ADD ./target/pigx-seata-server.jar ./
|
||||
|
||||
CMD sleep 180;java $JAVA_OPTS -jar pigx-seata-server.jar
|
||||
@@ -1,218 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 1999-2019 Seata.io Group.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-visual</artifactId>
|
||||
<version>5.1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>pigx-seata-server</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>pigx-seata-server</name>
|
||||
|
||||
<properties>
|
||||
<seata.version>1.6.1</seata.version>
|
||||
<logstash-logback-encoder.version>6.5</logstash-logback-encoder.version>
|
||||
<kafka-appender.version>0.2.0-RC2</kafka-appender.version>
|
||||
<jcommander.version>1.72</jcommander.version>
|
||||
<guava.version>27.0.1-jre</guava.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-dependencies</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-spring-autoconfigure-server</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-core</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-config-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>log4j</artifactId>
|
||||
<groupId>log4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-discovery-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-serializer-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-compressor-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-metrics-all</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-console</artifactId>
|
||||
<version>${seata.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- for database -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
<!-- if you run seata-server in IDE and use mysql8 as session store, please rewrite version to ${mysql8.jdbc.version}-->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
<!-- Copyright restrictions, do not reference this dependency.
|
||||
You can add this dependency to the '/seata/lib' directory of the seata-server when necessary.
|
||||
<dependency>
|
||||
<groupId>com.oracle.ojdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
<version>${ojdbc.version}</version>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.beust</groupId>
|
||||
<artifactId>jcommander</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- only for event bus -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- jedis -->
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.microwww</groupId>
|
||||
<artifactId>redis-server</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- logback -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-core</artifactId>
|
||||
</dependency>
|
||||
<!-- logback appenders -->
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.danielwegener</groupId>
|
||||
<artifactId>logback-kafka-appender</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!--undertow容器-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>pigx-seata-server</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<configuration>
|
||||
<mainClass>io.seata.server.PigxSeataServer</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
-326
@@ -1,326 +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;
|
||||
|
||||
import io.seata.common.exception.StoreException;
|
||||
import io.seata.core.exception.AbstractExceptionHandler;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.exception.TransactionExceptionCode;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.protocol.transaction.*;
|
||||
import io.seata.core.rpc.RpcContext;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The type Abstract tc inbound handler.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public abstract class AbstractTCInboundHandler extends AbstractExceptionHandler implements TCInboundHandler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTCInboundHandler.class);
|
||||
|
||||
@Override
|
||||
public GlobalBeginResponse handle(GlobalBeginRequest request, final RpcContext rpcContext) {
|
||||
GlobalBeginResponse response = new GlobalBeginResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalBeginRequest, GlobalBeginResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalBeginRequest request, GlobalBeginResponse response) throws TransactionException {
|
||||
try {
|
||||
doGlobalBegin(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"begin global request failed. xid=%s, msg=%s", response.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global begin.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalCommitResponse handle(GlobalCommitRequest request, final RpcContext rpcContext) {
|
||||
GlobalCommitResponse response = new GlobalCommitResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Committing);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalCommitRequest, GlobalCommitResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalCommitRequest request, GlobalCommitResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalCommit(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global commit request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionException(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalCommitRequest request, GlobalCommitResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global commit.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalRollbackResponse handle(GlobalRollbackRequest request, final RpcContext rpcContext) {
|
||||
GlobalRollbackResponse response = new GlobalRollbackResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Rollbacking);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalRollbackRequest, GlobalRollbackResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalRollbackRequest request, GlobalRollbackResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalRollback(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global rollback request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global rollback.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public BranchRegisterResponse handle(BranchRegisterRequest request, final RpcContext rpcContext) {
|
||||
BranchRegisterResponse response = new BranchRegisterResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchRegisterRequest, BranchRegisterResponse>() {
|
||||
@Override
|
||||
public void execute(BranchRegisterRequest request, BranchRegisterResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchRegister(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"branch register request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do branch register.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public BranchReportResponse handle(BranchReportRequest request, final RpcContext rpcContext) {
|
||||
BranchReportResponse response = new BranchReportResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchReportRequest, BranchReportResponse>() {
|
||||
@Override
|
||||
public void execute(BranchReportRequest request, BranchReportResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchReport(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore,
|
||||
String.format("branch report request failed. xid=%s, branchId=%s, msg=%s", request.getXid(),
|
||||
request.getBranchId(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do branch report.
|
||||
* @param request the request
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchReport(BranchReportRequest request, BranchReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalLockQueryResponse handle(GlobalLockQueryRequest request, final RpcContext rpcContext) {
|
||||
GlobalLockQueryResponse response = new GlobalLockQueryResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalLockQueryRequest, GlobalLockQueryResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalLockQueryRequest request, GlobalLockQueryResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doLockCheck(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global lock query request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do lock check.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalStatusResponse handle(GlobalStatusRequest request, final RpcContext rpcContext) {
|
||||
GlobalStatusResponse response = new GlobalStatusResponse();
|
||||
response.setGlobalStatus(GlobalStatus.UnKnown);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalStatusRequest, GlobalStatusResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalStatusRequest request, GlobalStatusResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalStatus(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global status request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionException(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalStatusRequest request, GlobalStatusResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global status.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalReportResponse handle(GlobalReportRequest request, final RpcContext rpcContext) {
|
||||
GlobalReportResponse response = new GlobalReportResponse();
|
||||
response.setGlobalStatus(request.getGlobalStatus());
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalReportRequest, GlobalReportResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalReportRequest request, GlobalReportResponse response)
|
||||
throws TransactionException {
|
||||
doGlobalReport(request, response, rpcContext);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global report.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
private void checkTransactionStatus(AbstractGlobalEndRequest request, AbstractGlobalEndResponse response) {
|
||||
try {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid(), false);
|
||||
if (globalSession != null) {
|
||||
response.setGlobalStatus(globalSession.getStatus());
|
||||
}
|
||||
else {
|
||||
response.setGlobalStatus(GlobalStatus.Finished);
|
||||
}
|
||||
}
|
||||
catch (Exception exx) {
|
||||
LOGGER.error("check transaction status error,{}]", exx.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,200 +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;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.server.env.ContainerHelper;
|
||||
import io.seata.server.store.StoreConfig;
|
||||
|
||||
import static io.seata.config.ConfigurationFactory.ENV_PROPERTY_KEY;
|
||||
|
||||
/**
|
||||
* The type Parameter parser.
|
||||
*
|
||||
* @author xingfudeshi @gmail.com
|
||||
*/
|
||||
public class ParameterParser {
|
||||
|
||||
private static final String PROGRAM_NAME = "sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows)";
|
||||
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
@Parameter(names = "--help", help = true)
|
||||
private boolean help;
|
||||
|
||||
@Parameter(names = { "--host", "-h" }, description = "The ip to register to registry center.", order = 1)
|
||||
private String host;
|
||||
|
||||
@Parameter(names = { "--port", "-p" }, description = "The port to listen.", order = 2)
|
||||
private int port;
|
||||
|
||||
@Parameter(names = { "--storeMode", "-m" }, description = "log store mode : file, db, redis", order = 3)
|
||||
private String storeMode;
|
||||
|
||||
@Parameter(names = { "--serverNode", "-n" },
|
||||
description = "server node id, such as 1, 2, 3.it will be generated according to the snowflake by default",
|
||||
order = 4)
|
||||
private Long serverNode;
|
||||
|
||||
@Parameter(names = { "--seataEnv", "-e" }, description = "The name used for multi-configuration isolation.",
|
||||
order = 5)
|
||||
private String seataEnv;
|
||||
|
||||
@Parameter(names = { "--sessionStoreMode", "-ssm" }, description = "session log store mode : file, db, redis",
|
||||
order = 6)
|
||||
private String sessionStoreMode;
|
||||
|
||||
@Parameter(names = { "--lockStoreMode", "-lsm" }, description = "lock log store mode : file, db, redis", order = 7)
|
||||
private String lockStoreMode;
|
||||
|
||||
/**
|
||||
* Instantiates a new Parameter parser.
|
||||
* @param args the args
|
||||
*/
|
||||
public ParameterParser(String... args) {
|
||||
this.init(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* startup args > docker env
|
||||
* @param args
|
||||
*/
|
||||
private void init(String[] args) {
|
||||
try {
|
||||
getCommandParameters(args);
|
||||
getEnvParameters();
|
||||
if (StringUtils.isNotBlank(seataEnv)) {
|
||||
System.setProperty(ENV_PROPERTY_KEY, seataEnv);
|
||||
}
|
||||
StoreConfig.setStartupParameter(storeMode, sessionStoreMode, lockStoreMode);
|
||||
}
|
||||
catch (ParameterException e) {
|
||||
printError(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getCommandParameters(String[] args) {
|
||||
JCommander jCommander = JCommander.newBuilder().addObject(this).build();
|
||||
jCommander.parse(args);
|
||||
if (help) {
|
||||
jCommander.setProgramName(PROGRAM_NAME);
|
||||
jCommander.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void getEnvParameters() {
|
||||
if (StringUtils.isBlank(seataEnv)) {
|
||||
seataEnv = ContainerHelper.getEnv();
|
||||
}
|
||||
if (StringUtils.isBlank(host)) {
|
||||
host = ContainerHelper.getHost();
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
if (serverNode == null) {
|
||||
serverNode = ContainerHelper.getServerNode();
|
||||
}
|
||||
}
|
||||
|
||||
private void printError(ParameterException e) {
|
||||
System.err.println("Option error " + e.getMessage());
|
||||
e.getJCommander().setProgramName(PROGRAM_NAME);
|
||||
e.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets host.
|
||||
* @return the host
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets port.
|
||||
* @return the port
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getStoreMode() {
|
||||
return storeMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getLockStoreMode() {
|
||||
return lockStoreMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets session store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getSessionStoreMode() {
|
||||
return sessionStoreMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is help boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server node.
|
||||
* @return the server node
|
||||
*/
|
||||
public Long getServerNode() {
|
||||
return serverNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets seata env
|
||||
* @return the name used for multi-configuration isolation.
|
||||
*/
|
||||
public String getSeataEnv() {
|
||||
return seataEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
if (null != System.getProperty(ENV_PROPERTY_KEY)) {
|
||||
System.clearProperty(ENV_PROPERTY_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +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;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author spilledyear@outlook.com
|
||||
*/
|
||||
@SpringBootApplication(scanBasePackages = { "io.seata" })
|
||||
public class PigxSeataServer {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// run the spring-boot application
|
||||
SpringApplication.run(PigxSeataServer.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,94 +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;
|
||||
|
||||
import io.seata.common.XID;
|
||||
import io.seata.common.thread.NamedThreadFactory;
|
||||
import io.seata.common.util.NetUtil;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.rpc.netty.NettyRemotingServer;
|
||||
import io.seata.core.rpc.netty.NettyServerConfig;
|
||||
import io.seata.server.coordinator.DefaultCoordinator;
|
||||
import io.seata.server.lock.LockerManagerFactory;
|
||||
import io.seata.server.metrics.MetricsManager;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.seata.spring.boot.autoconfigure.StarterConstants.REGEX_SPLIT_CHAR;
|
||||
import static io.seata.spring.boot.autoconfigure.StarterConstants.REGISTRY_PREFERED_NETWORKS;
|
||||
|
||||
/**
|
||||
* The type Server.
|
||||
*
|
||||
* @author slievrly
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
/**
|
||||
* The entry point of application.
|
||||
* @param args the input arguments
|
||||
*/
|
||||
public static void start(String[] args) {
|
||||
// initialize the parameter parser
|
||||
// Note that the parameter parser should always be the first line to execute.
|
||||
// Because, here we need to parse the parameters needed for startup.
|
||||
ParameterParser parameterParser = new ParameterParser(args);
|
||||
|
||||
// initialize the metrics
|
||||
MetricsManager.get().init();
|
||||
|
||||
ThreadPoolExecutor workingThreads = new ThreadPoolExecutor(NettyServerConfig.getMinServerPoolSize(),
|
||||
NettyServerConfig.getMaxServerPoolSize(), NettyServerConfig.getKeepAliveTime(), TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(NettyServerConfig.getMaxTaskQueueSize()),
|
||||
new NamedThreadFactory("ServerHandlerThread", NettyServerConfig.getMaxServerPoolSize()),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
// 127.0.0.1 and 0.0.0.0 are not valid here.
|
||||
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
|
||||
XID.setIpAddress(parameterParser.getHost());
|
||||
}
|
||||
else {
|
||||
String preferredNetworks = ConfigurationFactory.getInstance().getConfig(REGISTRY_PREFERED_NETWORKS);
|
||||
if (StringUtils.isNotBlank(preferredNetworks)) {
|
||||
XID.setIpAddress(NetUtil.getLocalIp(preferredNetworks.split(REGEX_SPLIT_CHAR)));
|
||||
}
|
||||
else {
|
||||
XID.setIpAddress(NetUtil.getLocalIp());
|
||||
}
|
||||
}
|
||||
|
||||
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
|
||||
XID.setPort(nettyRemotingServer.getListenPort());
|
||||
UUIDGenerator.init(parameterParser.getServerNode());
|
||||
// log store mode : file, db, redis
|
||||
SessionHolder.init();
|
||||
LockerManagerFactory.init();
|
||||
DefaultCoordinator coordinator = DefaultCoordinator.getInstance(nettyRemotingServer);
|
||||
coordinator.init();
|
||||
nettyRemotingServer.setHandler(coordinator);
|
||||
|
||||
// let ServerRunner do destroy instead ShutdownHook, see
|
||||
// https://github.com/seata/seata/issues/4028
|
||||
ServerRunner.addDisposable(coordinator);
|
||||
|
||||
nettyRemotingServer.init();
|
||||
}
|
||||
|
||||
}
|
||||
-129
@@ -1,129 +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;
|
||||
|
||||
import io.seata.common.holder.ObjectHolder;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.server.store.StoreConfig;
|
||||
import io.seata.spring.boot.autoconfigure.SeataCoreEnvironmentPostProcessor;
|
||||
import io.seata.spring.boot.autoconfigure.SeataServerEnvironmentPostProcessor;
|
||||
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
|
||||
import org.springframework.boot.context.logging.LoggingApplicationListener;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.event.GenericApplicationListener;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static io.seata.common.Constants.OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT;
|
||||
import static io.seata.common.DefaultValues.SERVICE_OFFSET_SPRING_BOOT;
|
||||
import static io.seata.core.constants.ConfigurationKeys.*;
|
||||
|
||||
/**
|
||||
* @author slievrly
|
||||
* @author funkye
|
||||
*/
|
||||
public class ServerApplicationListener implements GenericApplicationListener {
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(ResolvableType eventType) {
|
||||
return eventType.getRawClass() != null
|
||||
&& ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType.getRawClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (!(event instanceof ApplicationEnvironmentPreparedEvent)) {
|
||||
return;
|
||||
}
|
||||
ApplicationEnvironmentPreparedEvent environmentPreparedEvent = (ApplicationEnvironmentPreparedEvent) event;
|
||||
ConfigurableEnvironment environment = environmentPreparedEvent.getEnvironment();
|
||||
ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, environment);
|
||||
SeataCoreEnvironmentPostProcessor.init();
|
||||
SeataServerEnvironmentPostProcessor.init();
|
||||
// Load by priority
|
||||
System.setProperty("sessionMode", StoreConfig.getSessionMode().getName());
|
||||
System.setProperty("lockMode", StoreConfig.getLockMode().getName());
|
||||
|
||||
String[] args = environmentPreparedEvent.getArgs();
|
||||
|
||||
// port: -p > -D > env > yml > default
|
||||
|
||||
// -p 8091
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
setTargetPort(environment, args[i + 1], true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -Dserver.servicePort=8091
|
||||
String dPort = environment.getProperty(SERVER_SERVICE_PORT_CAMEL, String.class);
|
||||
if (StringUtils.isNotBlank(dPort)) {
|
||||
setTargetPort(environment, dPort, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// docker -e SEATA_PORT=8091
|
||||
String envPort = environment.getProperty(ENV_SEATA_PORT_KEY, String.class);
|
||||
if (StringUtils.isNotBlank(envPort)) {
|
||||
setTargetPort(environment, envPort, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// yml properties server.service-port=8091
|
||||
String configPort = environment.getProperty(SERVER_SERVICE_PORT_CONFIG, String.class);
|
||||
if (StringUtils.isNotBlank(configPort)) {
|
||||
setTargetPort(environment, configPort, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// server.port=7091
|
||||
String serverPort = environment.getProperty("server.port", String.class);
|
||||
if (StringUtils.isBlank(serverPort)) {
|
||||
serverPort = "8080";
|
||||
}
|
||||
String servicePort = String.valueOf(Integer.parseInt(serverPort) + SERVICE_OFFSET_SPRING_BOOT);
|
||||
setTargetPort(environment, servicePort, true);
|
||||
}
|
||||
|
||||
private void setTargetPort(ConfigurableEnvironment environment, String port, boolean needAddPropertySource) {
|
||||
// get rpc port first, use to logback-spring.xml, @see the class named
|
||||
// `SystemPropertyLoggerContextListener`
|
||||
System.setProperty(SERVER_SERVICE_PORT_CAMEL, port);
|
||||
|
||||
if (needAddPropertySource) {
|
||||
// add property source to the first position
|
||||
Properties pro = new Properties();
|
||||
pro.setProperty(SERVER_SERVICE_PORT_CONFIG, port);
|
||||
environment.getPropertySources().addFirst(new PropertiesPropertySource("serverProperties", pro));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* higher than LoggingApplicationListener
|
||||
* @return the order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return LoggingApplicationListener.DEFAULT_ORDER - 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,81 +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;
|
||||
|
||||
import io.seata.core.rpc.Disposable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
* @author spilledyear@outlook.com
|
||||
*/
|
||||
@Component
|
||||
public class ServerRunner implements CommandLineRunner, DisposableBean {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServerRunner.class);
|
||||
|
||||
private boolean started = Boolean.FALSE;
|
||||
|
||||
private static final List<Disposable> DISPOSABLE_LIST = new CopyOnWriteArrayList<>();
|
||||
|
||||
public static void addDisposable(Disposable disposable) {
|
||||
DISPOSABLE_LIST.add(disposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
Server.start(args);
|
||||
started = true;
|
||||
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
LOGGER.info("seata server started in {} millSeconds", cost);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
started = Boolean.FALSE;
|
||||
LOGGER.error("seata server start error: {} ", e.getMessage(), e);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean started() {
|
||||
return started;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll starting");
|
||||
}
|
||||
|
||||
for (Disposable disposable : DISPOSABLE_LIST) {
|
||||
disposable.destroy();
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll finish");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +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;
|
||||
|
||||
import io.seata.common.util.IdWorker;
|
||||
|
||||
/**
|
||||
* The type Uuid generator.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class UUIDGenerator {
|
||||
|
||||
private static volatile IdWorker idWorker;
|
||||
|
||||
/**
|
||||
* generate UUID using snowflake algorithm
|
||||
* @return UUID
|
||||
*/
|
||||
public static long generateUUID() {
|
||||
if (idWorker == null) {
|
||||
synchronized (UUIDGenerator.class) {
|
||||
if (idWorker == null) {
|
||||
init(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return idWorker.nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* init IdWorker
|
||||
* @param serverNode the server node id, consider as machine id in snowflake
|
||||
*/
|
||||
public static void init(Long serverNode) {
|
||||
idWorker = new IdWorker(serverNode);
|
||||
}
|
||||
|
||||
}
|
||||
-54
@@ -1,54 +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.auth;
|
||||
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import io.seata.core.protocol.RegisterRMRequest;
|
||||
import io.seata.core.protocol.RegisterTMRequest;
|
||||
import io.seata.core.rpc.RegisterCheckAuthHandler;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_SERVER_ENABLE_CHECK_AUTH;
|
||||
|
||||
/**
|
||||
* @author slievrly
|
||||
*/
|
||||
public abstract class AbstractCheckAuthHandler implements RegisterCheckAuthHandler {
|
||||
|
||||
private static final Boolean ENABLE_CHECK_AUTH = ConfigurationFactory.getInstance()
|
||||
.getBoolean(ConfigurationKeys.SERVER_ENABLE_CHECK_AUTH, DEFAULT_SERVER_ENABLE_CHECK_AUTH);
|
||||
|
||||
@Override
|
||||
public boolean regTransactionManagerCheckAuth(RegisterTMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegTransactionManagerCheck(request);
|
||||
}
|
||||
|
||||
public abstract boolean doRegTransactionManagerCheck(RegisterTMRequest request);
|
||||
|
||||
@Override
|
||||
public boolean regResourceManagerCheckAuth(RegisterRMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegResourceManagerCheck(request);
|
||||
}
|
||||
|
||||
public abstract boolean doRegResourceManagerCheck(RegisterRMRequest request);
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +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.auth;
|
||||
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
import io.seata.core.protocol.RegisterRMRequest;
|
||||
import io.seata.core.protocol.RegisterTMRequest;
|
||||
|
||||
/**
|
||||
* @author slievrly
|
||||
*/
|
||||
@LoadLevel(name = "defaultCheckAuthHandler", order = 100)
|
||||
public class DefaultCheckAuthHandler extends AbstractCheckAuthHandler {
|
||||
|
||||
@Override
|
||||
public boolean doRegTransactionManagerCheck(RegisterTMRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doRegResourceManagerCheck(RegisterRMRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +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.console.controller;
|
||||
|
||||
import io.seata.server.console.service.BranchSessionService;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Branch Session Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("console/branchSession")
|
||||
public class BranchSessionController {
|
||||
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +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.console.controller;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.service.GlobalLockService;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Global Lock Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/console/globalLock")
|
||||
public class GlobalLockController {
|
||||
|
||||
@Resource(type = GlobalLockService.class)
|
||||
private GlobalLockService globalLockService;
|
||||
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalLockVO> query(@ModelAttribute GlobalLockParam param) {
|
||||
return globalLockService.query(param);
|
||||
}
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +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.console.controller;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalSessionParam;
|
||||
import io.seata.server.console.service.GlobalSessionService;
|
||||
import io.seata.server.console.vo.GlobalSessionVO;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Global Session Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/console/globalSession")
|
||||
public class GlobalSessionController {
|
||||
|
||||
@Resource(type = GlobalSessionService.class)
|
||||
private GlobalSessionService globalSessionService;
|
||||
|
||||
/**
|
||||
* Query all globalSession
|
||||
* @param param param for query globalSession
|
||||
* @return the list of GlobalSessionVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalSessionVO> query(@ModelAttribute GlobalSessionParam param) {
|
||||
return globalSessionService.query(param);
|
||||
}
|
||||
|
||||
}
|
||||
-104
@@ -1,104 +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.console.impl.db;
|
||||
|
||||
import io.seata.common.ConfigurationKeys;
|
||||
import io.seata.common.exception.StoreException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.IOUtil;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.store.db.DataSourceProvider;
|
||||
import io.seata.core.store.db.sql.log.LogStoreSqlsFactory;
|
||||
import io.seata.server.console.service.BranchSessionService;
|
||||
import io.seata.server.console.vo.BranchSessionVO;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_STORE_DB_BRANCH_TABLE;
|
||||
|
||||
/**
|
||||
* Branch Session DataBase ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author lvekee 734843455@qq.com
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'db'.equals('${sessionMode}')}")
|
||||
public class BranchSessionDBServiceImpl implements BranchSessionService {
|
||||
|
||||
private String branchTable;
|
||||
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
public BranchSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
branchTable = configuration.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, DEFAULT_STORE_DB_BRANCH_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
throw new IllegalArgumentException("xid should not be blank");
|
||||
}
|
||||
|
||||
String whereCondition = " where xid = ? ";
|
||||
String branchSessionSQL = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllBranchSessionSQL(branchTable,
|
||||
whereCondition);
|
||||
|
||||
List<BranchSessionVO> list = new ArrayList<>();
|
||||
ResultSet rs = null;
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(branchSessionSQL)) {
|
||||
ps.setObject(1, xid);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(BranchSessionVO.convert(rs));
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs);
|
||||
}
|
||||
return PageResult.success(list, list.size(), 0, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
-146
@@ -1,146 +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.console.impl.db;
|
||||
|
||||
import io.seata.common.ConfigurationKeys;
|
||||
import io.seata.common.exception.StoreException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.IOUtil;
|
||||
import io.seata.common.util.PageUtil;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.store.db.DataSourceProvider;
|
||||
import io.seata.core.store.db.sql.lock.LockStoreSqlFactory;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.service.GlobalLockService;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_LOCK_DB_TABLE;
|
||||
|
||||
/**
|
||||
* Global Lock DB ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author lvekee 734843455@qq.com
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'db'.equals('${lockMode}')}")
|
||||
public class GlobalLockDBServiceImpl implements GlobalLockService {
|
||||
|
||||
private String lockTable;
|
||||
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
public GlobalLockDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
lockTable = configuration.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = this.getWhereConditionByParam(param, sqlParamList);
|
||||
|
||||
String sourceSql = LockStoreSqlFactory.getLogStoreSql(dbType).getAllLockSql(lockTable, whereCondition);
|
||||
String queryLockSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String lockCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
|
||||
List<GlobalLockVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(queryLockSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(lockCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalLockVO.convert(rs));
|
||||
}
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
private String getWhereConditionByParam(GlobalLockParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTableName())) {
|
||||
whereConditionBuilder.append(" and table_name = ? ");
|
||||
sqlParamList.add(param.getTableName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionId())) {
|
||||
whereConditionBuilder.append(" and transaction_id = ? ");
|
||||
sqlParamList.add(param.getTransactionId());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getBranchId())) {
|
||||
whereConditionBuilder.append(" and branch_id = ? ");
|
||||
sqlParamList.add(param.getBranchId());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(param.getTimeStart());
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(param.getTimeEnd());
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
|
||||
}
|
||||
-162
@@ -1,162 +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.console.impl.db;
|
||||
|
||||
import io.seata.common.ConfigurationKeys;
|
||||
import io.seata.common.exception.StoreException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.IOUtil;
|
||||
import io.seata.common.util.PageUtil;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.Configuration;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.store.db.DataSourceProvider;
|
||||
import io.seata.core.store.db.sql.log.LogStoreSqlsFactory;
|
||||
import io.seata.server.console.param.GlobalSessionParam;
|
||||
import io.seata.server.console.service.BranchSessionService;
|
||||
import io.seata.server.console.service.GlobalSessionService;
|
||||
import io.seata.server.console.vo.BranchSessionVO;
|
||||
import io.seata.server.console.vo.GlobalSessionVO;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
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.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_STORE_DB_GLOBAL_TABLE;
|
||||
|
||||
/**
|
||||
* Global Session DataBase ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author lvekee 734843455@qq.com
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'db'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionDBServiceImpl implements GlobalSessionService {
|
||||
|
||||
private String globalTable;
|
||||
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
|
||||
public GlobalSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
globalTable = configuration.getConfig(ConfigurationKeys.STORE_DB_GLOBAL_TABLE, DEFAULT_STORE_DB_GLOBAL_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = getWhereConditionByParam(param, sqlParamList);
|
||||
|
||||
String sourceSql = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllGlobalSessionSql(globalTable,
|
||||
whereCondition);
|
||||
String querySessionSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String sessionCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
|
||||
List<GlobalSessionVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(querySessionSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(sessionCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalSessionVO.convert(rs));
|
||||
}
|
||||
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
if (param.isWithBranch()) {
|
||||
for (GlobalSessionVO globalSessionVO : list) {
|
||||
PageResult<BranchSessionVO> pageResp = branchSessionService.queryByXid(globalSessionVO.getXid());
|
||||
globalSessionVO.setBranchSessionVOs(new HashSet<>(pageResp.getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
private String getWhereConditionByParam(GlobalSessionParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getApplicationId())) {
|
||||
whereConditionBuilder.append(" and application_id = ? ");
|
||||
sqlParamList.add(param.getApplicationId());
|
||||
}
|
||||
if (param.getStatus() != null) {
|
||||
whereConditionBuilder.append(" and status = ? ");
|
||||
sqlParamList.add(param.getStatus());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionName())) {
|
||||
whereConditionBuilder.append(" and transaction_name = ? ");
|
||||
sqlParamList.add(param.getTransactionName());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeStart()));
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeEnd()));
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
|
||||
}
|
||||
-40
@@ -1,40 +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.console.impl.file;
|
||||
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.service.BranchSessionService;
|
||||
import io.seata.server.console.vo.BranchSessionVO;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Branch Session File ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'file'.equals('${sessionMode}')}")
|
||||
public class BranchSessionFileServiceImpl implements BranchSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
throw new NotSupportYetException();
|
||||
}
|
||||
|
||||
}
|
||||
-159
@@ -1,159 +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.console.impl.file;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.lock.RowLock;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.service.GlobalLockService;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
import io.seata.server.lock.LockerManagerFactory;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.seata.common.util.StringUtils.isBlank;
|
||||
import static io.seata.server.console.vo.GlobalLockVO.convert;
|
||||
import static java.util.Objects.isNull;
|
||||
|
||||
/**
|
||||
* Global Lock File ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author miaoxueyu
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'file'.equals('${lockMode}')}")
|
||||
public class GlobalLockFileServiceImpl implements GlobalLockService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
checkParam(param);
|
||||
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
|
||||
final AtomicInteger total = new AtomicInteger();
|
||||
List<RowLock> result = allSessions.parallelStream().filter(obtainGlobalSessionPredicate(param))
|
||||
.flatMap(globalSession -> globalSession.getBranchSessions().stream())
|
||||
.filter(obtainBranchSessionPredicate(param))
|
||||
.flatMap(branchSession -> filterAndMap(param, branchSession))
|
||||
.peek(globalSession -> total.incrementAndGet()).collect(Collectors.toList());
|
||||
|
||||
return PageResult.build(convert(result), param.getPageNum(), param.getPageSize());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* filter with tableName and generate RowLock
|
||||
* @param param the query param
|
||||
* @param branchSession the branch session
|
||||
* @return the RowLock list
|
||||
*/
|
||||
private Stream<RowLock> filterAndMap(GlobalLockParam param, BranchSession branchSession) {
|
||||
|
||||
final String tableName = param.getTableName();
|
||||
|
||||
// get rowLock from branchSession
|
||||
final List<RowLock> rowLocks = LockerManagerFactory.getLockManager().collectRowLocks(branchSession);
|
||||
|
||||
if (StringUtils.isNotBlank(tableName)) {
|
||||
return rowLocks.parallelStream().filter(rowLock -> rowLock.getTableName().contains(param.getTableName()));
|
||||
}
|
||||
|
||||
return rowLocks.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* check the param
|
||||
* @param param the param
|
||||
*/
|
||||
private void checkParam(GlobalLockParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
|
||||
// verification data type
|
||||
try {
|
||||
Long.parseLong(param.getTransactionId());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
param.setTransactionId(null);
|
||||
}
|
||||
try {
|
||||
Long.parseLong(param.getBranchId());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
param.setBranchId(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the branch session condition
|
||||
* @param param condition for query branch session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super BranchSession> obtainBranchSessionPredicate(GlobalLockParam param) {
|
||||
return branchSession -> {
|
||||
// transactionId
|
||||
return (isBlank(param.getTransactionId())
|
||||
|| String.valueOf(branchSession.getTransactionId()).contains(param.getTransactionId()))
|
||||
|
||||
&&
|
||||
// branch id
|
||||
(isBlank(param.getBranchId()) || String.valueOf(branchSession.getBranchId()).contains(param.getBranchId()));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the global session condition
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainGlobalSessionPredicate(GlobalLockParam param) {
|
||||
|
||||
return globalSession -> {
|
||||
// first, there must be withBranchSession
|
||||
return CollectionUtils.isNotEmpty(globalSession.getBranchSessions())
|
||||
|
||||
&&
|
||||
// The second is other conditions
|
||||
// xid
|
||||
(isBlank(param.getXid()) || globalSession.getXid().contains(param.getXid()))
|
||||
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= globalSession.getBeginTime())
|
||||
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= globalSession.getBeginTime());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
-98
@@ -1,98 +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.console.impl.file;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalSessionParam;
|
||||
import io.seata.server.console.service.GlobalSessionService;
|
||||
import io.seata.server.console.vo.GlobalSessionVO;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
import io.seata.server.storage.SessionConverter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.seata.common.util.StringUtils.isBlank;
|
||||
import static java.util.Objects.isNull;
|
||||
|
||||
/**
|
||||
* Global Session File ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author miaoxueyu
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'file'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionFileServiceImpl implements GlobalSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
|
||||
final List<GlobalSession> filteredSessions = allSessions.parallelStream().filter(obtainPredicate(param))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return PageResult.build(SessionConverter.convertGlobalSession(filteredSessions), param.getPageNum(),
|
||||
param.getPageSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the condition
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainPredicate(GlobalSessionParam param) {
|
||||
|
||||
return session -> {
|
||||
return
|
||||
// xid
|
||||
(isBlank(param.getXid()) || session.getXid().contains(param.getXid()))
|
||||
|
||||
&&
|
||||
// applicationId
|
||||
(isBlank(param.getApplicationId()) || session.getApplicationId().contains(param.getApplicationId()))
|
||||
|
||||
&&
|
||||
// status
|
||||
(isNull(param.getStatus()) || Objects.equals(session.getStatus().getCode(), param.getStatus()))
|
||||
|
||||
&&
|
||||
// transactionName
|
||||
(isBlank(param.getTransactionName()) || session.getTransactionName().contains(param.getTransactionName()))
|
||||
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= session.getBeginTime())
|
||||
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= session.getBeginTime());
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
-66
@@ -1,66 +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.console.impl.redis;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.store.BranchTransactionDO;
|
||||
import io.seata.server.console.service.BranchSessionService;
|
||||
import io.seata.server.console.vo.BranchSessionVO;
|
||||
import io.seata.server.storage.redis.store.RedisTransactionStoreManager;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Branch Session Redis ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author doubleDimple
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'redis'.equals('${sessionMode}')}")
|
||||
public class BranchSessionRedisServiceImpl implements BranchSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
return PageResult.success();
|
||||
}
|
||||
|
||||
List<BranchSessionVO> branchSessionVos = new ArrayList<>();
|
||||
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
|
||||
List<BranchTransactionDO> branchSessionDos = instance.findBranchSessionByXid(xid);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(branchSessionDos)) {
|
||||
for (BranchTransactionDO branchSessionDo : branchSessionDos) {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
BeanUtils.copyProperties(branchSessionDo, branchSessionVO);
|
||||
branchSessionVos.add(branchSessionVO);
|
||||
}
|
||||
}
|
||||
|
||||
return PageResult.success(branchSessionVos, branchSessionVos.size(), 0, branchSessionVos.size());
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -1,121 +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.console.impl.redis;
|
||||
|
||||
import io.seata.common.util.BeanUtils;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.service.GlobalLockService;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
import io.seata.server.storage.redis.JedisPooledFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.seata.common.Constants.ROW_LOCK_KEY_SPLIT_CHAR;
|
||||
import static io.seata.common.exception.FrameworkErrorCode.ParameterRequired;
|
||||
import static io.seata.common.util.StringUtils.isNotBlank;
|
||||
import static io.seata.console.result.PageResult.checkPage;
|
||||
import static io.seata.core.constants.RedisKeyConstants.*;
|
||||
|
||||
/**
|
||||
* Global Lock Redis Service Impl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author doubleDimple
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'redis'.equals('${lockMode}')}")
|
||||
public class GlobalLockRedisServiceImpl implements GlobalLockService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
|
||||
int total = 0;
|
||||
List<GlobalLockVO> globalLockVos;
|
||||
checkPage(param);
|
||||
if (isNotBlank(param.getXid())) {
|
||||
globalLockVos = queryGlobalByXid(param.getXid());
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos, total, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
else if (isNotBlank(param.getTableName()) && isNotBlank(param.getPk()) && isNotBlank(param.getResourceId())) {
|
||||
// SEATA_ROW_LOCK_jdbc:mysql://116.62.62.26/seata-order^^^order^^^2188
|
||||
String tableName = param.getTableName();
|
||||
String pk = param.getPk();
|
||||
String resourceId = param.getResourceId();
|
||||
globalLockVos = queryGlobalLockByRowKey(buildRowKey(tableName, pk, resourceId));
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos, total, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
else {
|
||||
return PageResult.failure(ParameterRequired.getErrCode(),
|
||||
"only three parameters of tableName,pk,resourceId or Xid are supported");
|
||||
}
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> queryGlobalLockByRowKey(String buildRowKey) {
|
||||
return readGlobalLockByRowKey(buildRowKey);
|
||||
}
|
||||
|
||||
private String buildRowKey(String tableName, String pk, String resourceId) {
|
||||
return DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX + resourceId + SPLIT + tableName + SPLIT + pk;
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> queryGlobalByXid(String xid) {
|
||||
return readGlobalLockByXid(DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX + xid);
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> readGlobalLockByXid(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> mapGlobalKeys = jedis.hgetAll(key);
|
||||
if (CollectionUtils.isNotEmpty(mapGlobalKeys)) {
|
||||
List<String> rowLockKeys = new ArrayList<>();
|
||||
mapGlobalKeys.forEach((k, v) -> rowLockKeys.addAll(Arrays.asList(v.split(ROW_LOCK_KEY_SPLIT_CHAR))));
|
||||
for (String rowLoclKey : rowLockKeys) {
|
||||
Map<String, String> mapRowLockKey = jedis.hgetAll(rowLoclKey);
|
||||
GlobalLockVO vo = (GlobalLockVO) BeanUtils.mapToObject(mapRowLockKey, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vos;
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> readGlobalLockByRowKey(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> map = jedis.hgetAll(key);
|
||||
GlobalLockVO vo = (GlobalLockVO) BeanUtils.mapToObject(map, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
return vos;
|
||||
}
|
||||
|
||||
}
|
||||
-116
@@ -1,116 +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.console.impl.redis;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.server.console.param.GlobalSessionParam;
|
||||
import io.seata.server.console.service.GlobalSessionService;
|
||||
import io.seata.server.console.vo.GlobalSessionVO;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionCondition;
|
||||
import io.seata.server.storage.redis.store.RedisTransactionStoreManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.seata.common.exception.FrameworkErrorCode.ParameterRequired;
|
||||
import static io.seata.common.util.StringUtils.isBlank;
|
||||
import static io.seata.common.util.StringUtils.isNotBlank;
|
||||
import static io.seata.console.result.PageResult.checkPage;
|
||||
import static io.seata.server.storage.SessionConverter.convertToGlobalSessionVo;
|
||||
|
||||
/**
|
||||
* Global Session Redis ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author doubleDimple
|
||||
*/
|
||||
@Component
|
||||
@org.springframework.context.annotation.Configuration
|
||||
@ConditionalOnExpression("#{'redis'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionRedisServiceImpl implements GlobalSessionService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalSessionRedisServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
List<GlobalSessionVO> result = new ArrayList<>();
|
||||
Long total = 0L;
|
||||
if (param.getTimeStart() != null || param.getTimeEnd() != null) {
|
||||
// not support time range query
|
||||
LOGGER.debug("not supported according to time range query");
|
||||
return PageResult.failure(ParameterRequired.getErrCode(), "not supported according to time range query");
|
||||
}
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
|
||||
checkPage(param);
|
||||
|
||||
if (isBlank(param.getXid()) && param.getStatus() == null) {
|
||||
total = instance.countByGlobalSessions(GlobalStatus.values());
|
||||
globalSessions = instance.findGlobalSessionByPage(param.getPageNum(), param.getPageSize(),
|
||||
param.isWithBranch());
|
||||
}
|
||||
else {
|
||||
List<GlobalSession> globalSessionsNew = new ArrayList<>();
|
||||
if (isNotBlank(param.getXid())) {
|
||||
SessionCondition sessionCondition = new SessionCondition();
|
||||
sessionCondition.setXid(param.getXid());
|
||||
sessionCondition.setLazyLoadBranch(!param.isWithBranch());
|
||||
globalSessions = instance.readSession(sessionCondition);
|
||||
total = (long) globalSessions.size();
|
||||
}
|
||||
|
||||
if (param.getStatus() != null && GlobalStatus.get(param.getStatus()) != null) {
|
||||
if (CollectionUtils.isNotEmpty(globalSessions)) {
|
||||
globalSessionsNew = globalSessions.stream()
|
||||
.filter(globalSession -> globalSession.getStatus().getCode() == (param.getStatus()))
|
||||
.collect(Collectors.toList());
|
||||
total = (long) globalSessionsNew.size();
|
||||
}
|
||||
else {
|
||||
total = instance.countByGlobalSessions(new GlobalStatus[] { GlobalStatus.get(param.getStatus()) });
|
||||
globalSessionsNew = instance.readSessionStatusByPage(param);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
if (isNotBlank(param.getApplicationId())) {
|
||||
// not support
|
||||
LOGGER.debug("not supported according to applicationId query");
|
||||
}
|
||||
if (isNotBlank(param.getTransactionName())) {
|
||||
// not support
|
||||
LOGGER.debug("not supported according to transactionName query");
|
||||
}
|
||||
}
|
||||
globalSessions = globalSessionsNew.size() > 0 ? globalSessionsNew : globalSessions;
|
||||
}
|
||||
|
||||
convertToGlobalSessionVo(result, globalSessions);
|
||||
|
||||
return PageResult.success(result, total.intValue(), param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
}
|
||||
-116
@@ -1,116 +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.console.param;
|
||||
|
||||
import io.seata.console.param.BaseParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Global lock param
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalLockParam extends BaseParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 615412528070131284L;
|
||||
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
|
||||
/**
|
||||
* the table name
|
||||
*/
|
||||
private String tableName;
|
||||
|
||||
/**
|
||||
* the transaction id
|
||||
*/
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* the branch id
|
||||
*/
|
||||
private String branchId;
|
||||
|
||||
/**
|
||||
* the primary Key
|
||||
*/
|
||||
private String pk;
|
||||
|
||||
/**
|
||||
* the resourceId
|
||||
*/
|
||||
private String resourceId;
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public void setBranchId(String branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockParam{" + "xid='" + xid + '\'' + ", tableName='" + tableName + '\'' + ", transactionId='"
|
||||
+ transactionId + '\'' + ", branchId='" + branchId + '\'' + ", pk='" + pk + '\'' + ", resourceId='"
|
||||
+ resourceId + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-102
@@ -1,102 +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.console.param;
|
||||
|
||||
import io.seata.console.param.BaseParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Global session param
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalSessionParam extends BaseParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 115488252809011284L;
|
||||
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
|
||||
/**
|
||||
* the application id
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
/**
|
||||
* the global session status
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* the transaction name
|
||||
*/
|
||||
private String transactionName;
|
||||
|
||||
/**
|
||||
* if with branch true: with branch session false: no branch session
|
||||
*/
|
||||
private boolean withBranch;
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean isWithBranch() {
|
||||
return withBranch;
|
||||
}
|
||||
|
||||
public void setWithBranch(boolean withBranch) {
|
||||
this.withBranch = withBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionParam{" + "xid='" + xid + '\'' + ", applicationId='" + applicationId + '\'' + ", status="
|
||||
+ status + ", transactionName='" + transactionName + '\'' + ", withBranch=" + withBranch + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-35
@@ -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.server.console.service;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.vo.BranchSessionVO;
|
||||
|
||||
/**
|
||||
* Branch session service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface BranchSessionService {
|
||||
|
||||
/**
|
||||
* Query branch session by xid
|
||||
* @param xid the xid
|
||||
* @return the BranchSessionVO list
|
||||
*/
|
||||
PageResult<BranchSessionVO> queryByXid(String xid);
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +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.console.service;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
|
||||
/**
|
||||
* Global lock service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface GlobalLockService {
|
||||
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
PageResult<GlobalLockVO> query(GlobalLockParam param);
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +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.console.service;
|
||||
|
||||
import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalSessionParam;
|
||||
import io.seata.server.console.vo.GlobalSessionVO;
|
||||
|
||||
/**
|
||||
* Global session service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface GlobalSessionService {
|
||||
|
||||
/**
|
||||
* Query global session
|
||||
* @param param the param
|
||||
* @return the GlobalSessionVO list
|
||||
*/
|
||||
PageResult<GlobalSessionVO> query(GlobalSessionParam param);
|
||||
|
||||
}
|
||||
-213
@@ -1,213 +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.console.vo;
|
||||
|
||||
import io.seata.core.constants.ServerTableColumnsName;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* BranchSessionVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class BranchSessionVO {
|
||||
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
|
||||
private String branchId;
|
||||
|
||||
private String resourceGroupId;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private String branchType;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
|
||||
public BranchSessionVO() {
|
||||
|
||||
}
|
||||
|
||||
public BranchSessionVO(String xid, Long transactionId, Long branchId, String resourceGroupId, String resourceId,
|
||||
String branchType, Integer status, String clientId, String applicationData) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.branchId = String.valueOf(branchId);
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
this.resourceId = resourceId;
|
||||
this.branchType = branchType;
|
||||
this.status = status;
|
||||
this.clientId = clientId;
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
|
||||
public String getResourceGroupId() {
|
||||
return resourceGroupId;
|
||||
}
|
||||
|
||||
public void setResourceGroupId(String resourceGroupId) {
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
|
||||
public void setBranchType(String branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public static BranchSessionVO convert(ResultSet rs) throws SQLException {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
branchSessionVO.setXid(rs.getString(ServerTableColumnsName.BRANCH_TABLE_XID));
|
||||
branchSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_TRANSACTION_ID));
|
||||
branchSessionVO.setBranchId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_BRANCH_ID));
|
||||
branchSessionVO.setResourceGroupId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_GROUP_ID));
|
||||
branchSessionVO.setResourceId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_ID));
|
||||
branchSessionVO.setBranchType(rs.getString(ServerTableColumnsName.BRANCH_TABLE_BRANCH_TYPE));
|
||||
branchSessionVO.setStatus(rs.getInt(ServerTableColumnsName.BRANCH_TABLE_STATUS));
|
||||
branchSessionVO.setClientId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_CLIENT_ID));
|
||||
branchSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.BRANCH_TABLE_APPLICATION_DATA));
|
||||
Date gmtCreateTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
branchSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Date gmtModifiedTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
branchSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return branchSessionVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BranchSessionVO that = (BranchSessionVO) o;
|
||||
return Objects.equals(xid, that.xid) && Objects.equals(transactionId, that.transactionId)
|
||||
&& Objects.equals(branchId, that.branchId) && Objects.equals(resourceGroupId, that.resourceGroupId)
|
||||
&& Objects.equals(resourceId, that.resourceId) && Objects.equals(branchType, that.branchType)
|
||||
&& Objects.equals(status, that.status) && Objects.equals(clientId, that.clientId)
|
||||
&& Objects.equals(applicationData, that.applicationData) && Objects.equals(gmtCreate, that.gmtCreate)
|
||||
&& Objects.equals(gmtModified, that.gmtModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(xid, transactionId, branchId, resourceGroupId, resourceId, branchType, status, clientId,
|
||||
applicationData, gmtCreate, gmtModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BranchSessionVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", branchId=" + branchId
|
||||
+ ", resourceGroupId='" + resourceGroupId + '\'' + ", resourceId='" + resourceId + '\''
|
||||
+ ", branchType='" + branchType + '\'' + ", status=" + status + ", clientId='" + clientId + '\''
|
||||
+ ", applicationData='" + applicationData + '\'' + ", gmtCreate=" + gmtCreate + ", gmtModified="
|
||||
+ gmtModified + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-188
@@ -1,188 +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.console.vo;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.core.constants.ServerTableColumnsName;
|
||||
import io.seata.core.lock.RowLock;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* GlobalLockVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author miaoxueyu
|
||||
*/
|
||||
public class GlobalLockVO {
|
||||
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
|
||||
private String branchId;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private String tableName;
|
||||
|
||||
private String pk;
|
||||
|
||||
private String rowKey;
|
||||
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
|
||||
/**
|
||||
* convert RowLock list to GlobalLockVO list
|
||||
* @param rowLocks the RowLock list
|
||||
* @return the GlobalLockVO list
|
||||
*/
|
||||
public static List<GlobalLockVO> convert(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<GlobalLockVO> result = new ArrayList<>(rowLocks.size());
|
||||
for (RowLock rowLock : rowLocks) {
|
||||
result.add(convert(rowLock));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert RowLock to GlobalLockVO
|
||||
* @param rowLock the RowLock
|
||||
* @return the GlobalLockVO
|
||||
*/
|
||||
public static GlobalLockVO convert(RowLock rowLock) {
|
||||
final GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setXid(rowLock.getXid());
|
||||
globalLockVO.setTransactionId(rowLock.getTransactionId());
|
||||
globalLockVO.setBranchId(rowLock.getBranchId());
|
||||
globalLockVO.setResourceId(rowLock.getResourceId());
|
||||
globalLockVO.setTableName(rowLock.getTableName());
|
||||
globalLockVO.setPk(rowLock.getPk());
|
||||
globalLockVO.setRowKey(rowLock.getRowKey());
|
||||
return globalLockVO;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public String getRowKey() {
|
||||
return rowKey;
|
||||
}
|
||||
|
||||
public void setRowKey(String rowKey) {
|
||||
this.rowKey = rowKey;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public static GlobalLockVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setRowKey(rs.getString(ServerTableColumnsName.LOCK_TABLE_ROW_KEY));
|
||||
globalLockVO.setXid(rs.getString(ServerTableColumnsName.LOCK_TABLE_XID));
|
||||
globalLockVO.setTransactionId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_TRANSACTION_ID));
|
||||
globalLockVO.setBranchId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_BRANCH_ID));
|
||||
globalLockVO.setResourceId(rs.getString(ServerTableColumnsName.LOCK_TABLE_RESOURCE_ID));
|
||||
globalLockVO.setTableName(rs.getString(ServerTableColumnsName.LOCK_TABLE_TABLE_NAME));
|
||||
globalLockVO.setPk(rs.getString(ServerTableColumnsName.LOCK_TABLE_PK));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalLockVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalLockVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalLockVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", branchId=" + branchId
|
||||
+ ", resourceId='" + resourceId + '\'' + ", tableName='" + tableName + '\'' + ", pk='" + pk + '\''
|
||||
+ ", rowKey='" + rowKey + '\'' + ", gmtCreate=" + gmtCreate + ", gmtModified=" + gmtModified + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-203
@@ -1,203 +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.console.vo;
|
||||
|
||||
import io.seata.core.constants.ServerTableColumnsName;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* GlobalSessionVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalSessionVO {
|
||||
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String applicationId;
|
||||
|
||||
private String transactionServiceGroup;
|
||||
|
||||
private String transactionName;
|
||||
|
||||
private Long timeout;
|
||||
|
||||
private Long beginTime;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
|
||||
private Set<BranchSessionVO> branchSessionVOs;
|
||||
|
||||
public GlobalSessionVO() {
|
||||
|
||||
}
|
||||
|
||||
public GlobalSessionVO(String xid, Long transactionId, Integer status, String applicationId,
|
||||
String transactionServiceGroup, String transactionName, Long timeout, Long beginTime,
|
||||
String applicationData, Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.status = status;
|
||||
this.applicationId = applicationId;
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
this.transactionName = transactionName;
|
||||
this.timeout = timeout;
|
||||
this.beginTime = beginTime;
|
||||
this.applicationData = applicationData;
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public String getTransactionServiceGroup() {
|
||||
return transactionServiceGroup;
|
||||
}
|
||||
|
||||
public void setTransactionServiceGroup(String transactionServiceGroup) {
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
}
|
||||
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
|
||||
public Long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(Long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public Long getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
public void setBeginTime(Long beginTime) {
|
||||
this.beginTime = beginTime;
|
||||
}
|
||||
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public Set<BranchSessionVO> getBranchSessionVOs() {
|
||||
return branchSessionVOs;
|
||||
}
|
||||
|
||||
public void setBranchSessionVOs(Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
|
||||
public static GlobalSessionVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalSessionVO globalSessionVO = new GlobalSessionVO();
|
||||
globalSessionVO.setXid(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_XID));
|
||||
globalSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_ID));
|
||||
globalSessionVO.setStatus(rs.getInt(ServerTableColumnsName.GLOBAL_TABLE_STATUS));
|
||||
globalSessionVO.setApplicationId(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_ID));
|
||||
globalSessionVO.setTransactionServiceGroup(
|
||||
rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_SERVICE_GROUP));
|
||||
globalSessionVO.setTransactionName(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_NAME));
|
||||
globalSessionVO.setTimeout(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TIMEOUT));
|
||||
globalSessionVO.setBeginTime(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_BEGIN_TIME));
|
||||
globalSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_DATA));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalSessionVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", status=" + status
|
||||
+ ", applicationId='" + applicationId + '\'' + ", transactionServiceGroup='" + transactionServiceGroup
|
||||
+ '\'' + ", transactionName='" + transactionName + '\'' + ", timeout=" + timeout + ", beginTime="
|
||||
+ beginTime + ", applicationData='" + applicationData + '\'' + ", gmtCreate=" + gmtCreate
|
||||
+ ", gmtModified=" + gmtModified + ", branchSessionVOs=" + branchSessionVOs + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-44
@@ -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.controller;
|
||||
|
||||
import io.seata.server.ServerRunner;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* @author spilledyear@outlook.com
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping
|
||||
public class HealthController {
|
||||
|
||||
private static final String OK = "ok";
|
||||
|
||||
private static final String NOT_OK = "not_ok";
|
||||
|
||||
@Autowired
|
||||
private ServerRunner serverRunner;
|
||||
|
||||
@RequestMapping("/health")
|
||||
@ResponseBody
|
||||
String healthCheck() {
|
||||
return serverRunner.started() ? OK : NOT_OK;
|
||||
}
|
||||
|
||||
}
|
||||
-251
@@ -1,251 +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.coordinator;
|
||||
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.exception.BranchTransactionException;
|
||||
import io.seata.core.exception.GlobalTransactionException;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.exception.TransactionExceptionCode;
|
||||
import io.seata.core.model.BranchStatus;
|
||||
import io.seata.core.model.BranchType;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.protocol.transaction.BranchCommitRequest;
|
||||
import io.seata.core.protocol.transaction.BranchCommitResponse;
|
||||
import io.seata.core.protocol.transaction.BranchRollbackRequest;
|
||||
import io.seata.core.protocol.transaction.BranchRollbackResponse;
|
||||
import io.seata.core.rpc.RemotingServer;
|
||||
import io.seata.server.lock.LockManager;
|
||||
import io.seata.server.lock.LockerManagerFactory;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionHelper;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import static io.seata.core.exception.TransactionExceptionCode.*;
|
||||
|
||||
/**
|
||||
* The type abstract core.
|
||||
*
|
||||
* @author ph3636
|
||||
*/
|
||||
public abstract class AbstractCore implements Core {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCore.class);
|
||||
|
||||
protected LockManager lockManager = LockerManagerFactory.getLockManager();
|
||||
|
||||
protected RemotingServer remotingServer;
|
||||
|
||||
public AbstractCore(RemotingServer remotingServer) {
|
||||
if (remotingServer == null) {
|
||||
throw new IllegalArgumentException("remotingServer must be not null");
|
||||
}
|
||||
this.remotingServer = remotingServer;
|
||||
}
|
||||
|
||||
public abstract BranchType getHandleBranchType();
|
||||
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
|
||||
return SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSessionStatusCheck(globalSession);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
|
||||
applicationData, lockKeys, clientId);
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
branchSessionLock(globalSession, branchSession);
|
||||
try {
|
||||
globalSession.addBranch(branchSession);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
branchSessionUnlock(branchSession);
|
||||
throw new BranchTransactionException(FailedToAddBranch,
|
||||
String.format("Failed to store branch xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
ex);
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
|
||||
}
|
||||
return branchSession.getBranchId();
|
||||
});
|
||||
}
|
||||
|
||||
protected void globalSessionStatusCheck(GlobalSession globalSession) throws GlobalTransactionException {
|
||||
if (!globalSession.isActive()) {
|
||||
throw new GlobalTransactionException(GlobalTransactionNotActive, String.format(
|
||||
"Could not register branch into global session xid = %s status = %s, cause by globalSession not active",
|
||||
globalSession.getXid(), globalSession.getStatus()));
|
||||
}
|
||||
if (globalSession.getStatus() != GlobalStatus.Begin) {
|
||||
throw new GlobalTransactionException(GlobalTransactionStatusInvalid,
|
||||
String.format(
|
||||
"Could not register branch into global session xid = %s status = %s while expecting %s",
|
||||
globalSession.getXid(), globalSession.getStatus(), GlobalStatus.Begin));
|
||||
}
|
||||
}
|
||||
|
||||
protected void branchSessionLock(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
|
||||
}
|
||||
|
||||
protected void branchSessionUnlock(BranchSession branchSession) throws TransactionException {
|
||||
|
||||
}
|
||||
|
||||
private GlobalSession assertGlobalSessionNotNull(String xid, boolean withBranchSessions)
|
||||
throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, withBranchSessions);
|
||||
if (globalSession == null) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.GlobalTransactionNotExist,
|
||||
String.format("Could not found global transaction xid = %s, may be has finished.", xid));
|
||||
}
|
||||
return globalSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, true);
|
||||
BranchSession branchSession = globalSession.getBranch(branchId);
|
||||
if (branchSession == null) {
|
||||
throw new BranchTransactionException(BranchTransactionNotExist,
|
||||
String.format("Could not found branch session xid = %s branchId = %s", xid, branchId));
|
||||
}
|
||||
branchSession.setApplicationData(applicationData);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
globalSession.changeBranchStatus(branchSession, status);
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Report branch status successfully, xid = {}, branchId = {}", globalSession.getXid(),
|
||||
branchSession.getBranchId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
try {
|
||||
BranchCommitRequest request = new BranchCommitRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchCommitSend(request, globalSession, branchSession);
|
||||
}
|
||||
catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchCommitRequest,
|
||||
String.format("Send branch commit failed, xid = %s branchId = %s", branchSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected BranchStatus branchCommitSend(BranchCommitRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchCommitResponse response = (BranchCommitResponse) remotingServer
|
||||
.sendSyncRequest(branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
try {
|
||||
BranchRollbackRequest request = new BranchRollbackRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchRollbackSend(request, globalSession, branchSession);
|
||||
}
|
||||
catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchRollbackRequest,
|
||||
String.format("Send branch rollback failed, xid = %s branchId = %s", branchSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected BranchStatus branchRollbackSend(BranchRollbackRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchRollbackResponse response = (BranchRollbackResponse) remotingServer
|
||||
.sendSyncRequest(branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus)
|
||||
throws TransactionException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +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.coordinator;
|
||||
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
|
||||
/**
|
||||
* The interface Core.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public interface Core extends TransactionCoordinatorInbound, TransactionCoordinatorOutbound {
|
||||
|
||||
/**
|
||||
* Do global commit.
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global commit.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Do global rollback.
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global rollback.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Do global report.
|
||||
* @param globalSession the global session
|
||||
* @param xid Transaction id.
|
||||
* @param param the global status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus param) throws TransactionException;
|
||||
|
||||
}
|
||||
-614
@@ -1,614 +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.coordinator;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.seata.common.thread.NamedThreadFactory;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.DurationUtil;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.protocol.AbstractMessage;
|
||||
import io.seata.core.protocol.AbstractResultMessage;
|
||||
import io.seata.core.protocol.transaction.*;
|
||||
import io.seata.core.rpc.Disposable;
|
||||
import io.seata.core.rpc.RemotingServer;
|
||||
import io.seata.core.rpc.RpcContext;
|
||||
import io.seata.core.rpc.TransactionMessageHandler;
|
||||
import io.seata.core.rpc.netty.ChannelManager;
|
||||
import io.seata.core.rpc.netty.NettyRemotingServer;
|
||||
import io.seata.server.AbstractTCInboundHandler;
|
||||
import io.seata.server.metrics.MetricsPublisher;
|
||||
import io.seata.server.session.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static io.seata.common.Constants.*;
|
||||
import static io.seata.common.DefaultValues.*;
|
||||
|
||||
/**
|
||||
* The type Default coordinator.
|
||||
*/
|
||||
public class DefaultCoordinator extends AbstractTCInboundHandler implements TransactionMessageHandler, Disposable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCoordinator.class);
|
||||
|
||||
private static final int TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS = 5000;
|
||||
|
||||
/**
|
||||
* The constant COMMITTING_RETRY_PERIOD.
|
||||
*/
|
||||
protected static final long COMMITTING_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.COMMITING_RETRY_PERIOD,
|
||||
DEFAULT_COMMITING_RETRY_PERIOD);
|
||||
|
||||
/**
|
||||
* The constant ASYNC_COMMITTING_RETRY_PERIOD.
|
||||
*/
|
||||
protected static final long ASYNC_COMMITTING_RETRY_PERIOD = CONFIG
|
||||
.getLong(ConfigurationKeys.ASYNC_COMMITING_RETRY_PERIOD, DEFAULT_ASYNC_COMMITTING_RETRY_PERIOD);
|
||||
|
||||
/**
|
||||
* The constant ROLLBACKING_RETRY_PERIOD.
|
||||
*/
|
||||
protected static final long ROLLBACKING_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.ROLLBACKING_RETRY_PERIOD,
|
||||
DEFAULT_ROLLBACKING_RETRY_PERIOD);
|
||||
|
||||
/**
|
||||
* The constant TIMEOUT_RETRY_PERIOD.
|
||||
*/
|
||||
protected static final long TIMEOUT_RETRY_PERIOD = CONFIG.getLong(ConfigurationKeys.TIMEOUT_RETRY_PERIOD,
|
||||
DEFAULT_TIMEOUT_RETRY_PERIOD);
|
||||
|
||||
/**
|
||||
* The Transaction undo log delete period.
|
||||
*/
|
||||
protected static final long UNDO_LOG_DELETE_PERIOD = CONFIG
|
||||
.getLong(ConfigurationKeys.TRANSACTION_UNDO_LOG_DELETE_PERIOD, DEFAULT_UNDO_LOG_DELETE_PERIOD);
|
||||
|
||||
/**
|
||||
* The Transaction undo log delay delete period
|
||||
*/
|
||||
protected static final long UNDO_LOG_DELAY_DELETE_PERIOD = 3 * 60 * 1000;
|
||||
|
||||
private static final int ALWAYS_RETRY_BOUNDARY = 0;
|
||||
|
||||
/**
|
||||
* default branch async queue size
|
||||
*/
|
||||
private static final int DEFAULT_BRANCH_ASYNC_QUEUE_SIZE = 5000;
|
||||
|
||||
/**
|
||||
* the pool size of branch asynchronous remove thread pool
|
||||
*/
|
||||
private static final int BRANCH_ASYNC_POOL_SIZE = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
private static final Duration MAX_COMMIT_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(
|
||||
ConfigurationKeys.MAX_COMMIT_RETRY_TIMEOUT, DurationUtil.DEFAULT_DURATION,
|
||||
DEFAULT_MAX_COMMIT_RETRY_TIMEOUT);
|
||||
|
||||
private static final Duration MAX_ROLLBACK_RETRY_TIMEOUT = ConfigurationFactory.getInstance().getDuration(
|
||||
ConfigurationKeys.MAX_ROLLBACK_RETRY_TIMEOUT, DurationUtil.DEFAULT_DURATION,
|
||||
DEFAULT_MAX_ROLLBACK_RETRY_TIMEOUT);
|
||||
|
||||
private static final boolean ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE = ConfigurationFactory.getInstance().getBoolean(
|
||||
ConfigurationKeys.ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE, DEFAULT_ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE);
|
||||
|
||||
private final ScheduledThreadPoolExecutor retryRollbacking = new ScheduledThreadPoolExecutor(1,
|
||||
new NamedThreadFactory(RETRY_ROLLBACKING, 1));
|
||||
|
||||
private final ScheduledThreadPoolExecutor retryCommitting = new ScheduledThreadPoolExecutor(1,
|
||||
new NamedThreadFactory(RETRY_COMMITTING, 1));
|
||||
|
||||
private final ScheduledThreadPoolExecutor asyncCommitting = new ScheduledThreadPoolExecutor(1,
|
||||
new NamedThreadFactory(ASYNC_COMMITTING, 1));
|
||||
|
||||
private final ScheduledThreadPoolExecutor timeoutCheck = new ScheduledThreadPoolExecutor(1,
|
||||
new NamedThreadFactory(TX_TIMEOUT_CHECK, 1));
|
||||
|
||||
private final ScheduledThreadPoolExecutor undoLogDelete = new ScheduledThreadPoolExecutor(1,
|
||||
new NamedThreadFactory(UNDOLOG_DELETE, 1));
|
||||
|
||||
private final GlobalStatus[] rollbackingStatuses = new GlobalStatus[] { GlobalStatus.TimeoutRollbacking,
|
||||
GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.RollbackRetrying, GlobalStatus.Rollbacking };
|
||||
|
||||
private final GlobalStatus[] retryCommittingStatuses = new GlobalStatus[] { GlobalStatus.Committing,
|
||||
GlobalStatus.CommitRetrying };
|
||||
|
||||
private final ThreadPoolExecutor branchRemoveExecutor = new ThreadPoolExecutor(BRANCH_ASYNC_POOL_SIZE,
|
||||
BRANCH_ASYNC_POOL_SIZE, Integer.MAX_VALUE, TimeUnit.MILLISECONDS,
|
||||
new ArrayBlockingQueue<>(
|
||||
CONFIG.getInt(ConfigurationKeys.SESSION_BRANCH_ASYNC_QUEUE_SIZE, DEFAULT_BRANCH_ASYNC_QUEUE_SIZE)),
|
||||
new NamedThreadFactory("branchSessionRemove", BRANCH_ASYNC_POOL_SIZE),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
private RemotingServer remotingServer;
|
||||
|
||||
private final DefaultCore core;
|
||||
|
||||
private static volatile DefaultCoordinator instance;
|
||||
|
||||
/**
|
||||
* Instantiates a new Default coordinator.
|
||||
* @param remotingServer the remoting server
|
||||
*/
|
||||
private DefaultCoordinator(RemotingServer remotingServer) {
|
||||
if (remotingServer == null) {
|
||||
throw new IllegalArgumentException("RemotingServer not allowed be null.");
|
||||
}
|
||||
this.remotingServer = remotingServer;
|
||||
this.core = new DefaultCore(remotingServer);
|
||||
}
|
||||
|
||||
public static DefaultCoordinator getInstance(RemotingServer remotingServer) {
|
||||
if (null == instance) {
|
||||
synchronized (DefaultCoordinator.class) {
|
||||
if (null == instance) {
|
||||
instance = new DefaultCoordinator(remotingServer);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static DefaultCoordinator getInstance() {
|
||||
if (null == instance) {
|
||||
throw new IllegalArgumentException("The instance has not been created.");
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous remove branch
|
||||
* @param globalSession the globalSession
|
||||
* @param branchSession the branchSession
|
||||
*/
|
||||
public void doBranchRemoveAsync(GlobalSession globalSession, BranchSession branchSession) {
|
||||
if (globalSession == null) {
|
||||
return;
|
||||
}
|
||||
branchRemoveExecutor.execute(new BranchRemoveTask(globalSession, branchSession));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous remove all branch
|
||||
* @param globalSession the globalSession
|
||||
*/
|
||||
public void doBranchRemoveAllAsync(GlobalSession globalSession) {
|
||||
if (globalSession == null) {
|
||||
return;
|
||||
}
|
||||
branchRemoveExecutor.execute(new BranchRemoveTask(globalSession));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
response.setXid(core.begin(rpcContext.getApplicationId(), rpcContext.getTransactionServiceGroup(),
|
||||
request.getTransactionName(), request.getTimeout()));
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info(
|
||||
"Begin new global transaction applicationId: {},transactionServiceGroup: {}, transactionName: {},timeout:{},xid:{}",
|
||||
rpcContext.getApplicationId(), rpcContext.getTransactionServiceGroup(),
|
||||
request.getTransactionName(), request.getTimeout(), response.getXid());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setGlobalStatus(core.commit(request.getXid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
RpcContext rpcContext) throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setGlobalStatus(core.rollback(request.getXid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setGlobalStatus(core.getStatus(request.getXid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setGlobalStatus(core.globalReport(request.getXid(), request.getGlobalStatus()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
|
||||
RpcContext rpcContext) throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setBranchId(core.branchRegister(request.getBranchType(), request.getResourceId(),
|
||||
rpcContext.getClientId(), request.getXid(), request.getApplicationData(), request.getLockKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBranchReport(BranchReportRequest request, BranchReportResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(request.getBranchId()));
|
||||
core.branchReport(request.getBranchType(), request.getXid(), request.getBranchId(), request.getStatus(),
|
||||
request.getApplicationData());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response, RpcContext rpcContext)
|
||||
throws TransactionException {
|
||||
MDC.put(RootContext.MDC_KEY_XID, request.getXid());
|
||||
response.setLockable(core.lockQuery(request.getBranchType(), request.getResourceId(), request.getXid(),
|
||||
request.getLockKey()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeout check.
|
||||
*/
|
||||
protected void timeoutCheck() {
|
||||
SessionCondition sessionCondition = new SessionCondition(GlobalStatus.Begin);
|
||||
sessionCondition.setLazyLoadBranch(true);
|
||||
Collection<GlobalSession> beginGlobalsessions = SessionHolder.getRootSessionManager()
|
||||
.findGlobalSessions(sessionCondition);
|
||||
if (CollectionUtils.isEmpty(beginGlobalsessions)) {
|
||||
return;
|
||||
}
|
||||
if (!beginGlobalsessions.isEmpty() && LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Global transaction timeout check begin, size: {}", beginGlobalsessions.size());
|
||||
}
|
||||
SessionHelper.forEach(beginGlobalsessions, globalSession -> {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(globalSession.getXid() + " " + globalSession.getStatus() + " "
|
||||
+ globalSession.getBeginTime() + " " + globalSession.getTimeout());
|
||||
}
|
||||
SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
if (globalSession.getStatus() != GlobalStatus.Begin || !globalSession.isTimeout()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGGER.info("Global transaction[{}] is timeout and will be rollback.", globalSession.getXid());
|
||||
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
globalSession.close();
|
||||
globalSession.setStatus(GlobalStatus.TimeoutRollbacking);
|
||||
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRetryRollbackingSessionManager());
|
||||
SessionHolder.getRetryRollbackingSessionManager().addGlobalSession(globalSession);
|
||||
|
||||
// transaction timeout and start rollbacking event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, GlobalStatus.TimeoutRollbacking.name(), false,
|
||||
false);
|
||||
|
||||
return true;
|
||||
});
|
||||
});
|
||||
if (!beginGlobalsessions.isEmpty() && LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("Global transaction timeout check end. ");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle retry rollbacking.
|
||||
*/
|
||||
protected void handleRetryRollbacking() {
|
||||
SessionCondition sessionCondition = new SessionCondition(rollbackingStatuses);
|
||||
sessionCondition.setLazyLoadBranch(true);
|
||||
Collection<GlobalSession> rollbackingSessions = SessionHolder.getRetryRollbackingSessionManager()
|
||||
.findGlobalSessions(sessionCondition);
|
||||
if (CollectionUtils.isEmpty(rollbackingSessions)) {
|
||||
return;
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
SessionHelper.forEach(rollbackingSessions, rollbackingSession -> {
|
||||
try {
|
||||
// prevent repeated rollback
|
||||
if (rollbackingSession.getStatus() == GlobalStatus.Rollbacking && !rollbackingSession.isDeadSession()) {
|
||||
// The function of this 'return' is 'continue'.
|
||||
return;
|
||||
}
|
||||
if (isRetryTimeout(now, MAX_ROLLBACK_RETRY_TIMEOUT.toMillis(), rollbackingSession.getBeginTime())) {
|
||||
if (ROLLBACK_RETRY_TIMEOUT_UNLOCK_ENABLE) {
|
||||
rollbackingSession.clean();
|
||||
}
|
||||
// Prevent thread safety issues
|
||||
SessionHolder.getRetryRollbackingSessionManager().removeGlobalSession(rollbackingSession);
|
||||
LOGGER.error("Global transaction rollback retry timeout and has removed [{}]",
|
||||
rollbackingSession.getXid());
|
||||
|
||||
SessionHelper.endRollbackFailed(rollbackingSession, true, true);
|
||||
|
||||
// The function of this 'return' is 'continue'.
|
||||
return;
|
||||
}
|
||||
rollbackingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
core.doGlobalRollback(rollbackingSession, true);
|
||||
}
|
||||
catch (TransactionException ex) {
|
||||
LOGGER.info("Failed to retry rollbacking [{}] {} {}", rollbackingSession.getXid(), ex.getCode(),
|
||||
ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle retry committing.
|
||||
*/
|
||||
protected void handleRetryCommitting() {
|
||||
SessionCondition retryCommittingSessionCondition = new SessionCondition(retryCommittingStatuses);
|
||||
retryCommittingSessionCondition.setLazyLoadBranch(true);
|
||||
Collection<GlobalSession> committingSessions = SessionHolder.getRetryCommittingSessionManager()
|
||||
.findGlobalSessions(retryCommittingSessionCondition);
|
||||
if (CollectionUtils.isEmpty(committingSessions)) {
|
||||
return;
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
SessionHelper.forEach(committingSessions, committingSession -> {
|
||||
try {
|
||||
// prevent repeated commit
|
||||
if (committingSession.getStatus() == GlobalStatus.Committing && !committingSession.isDeadSession()) {
|
||||
// The function of this 'return' is 'continue'.
|
||||
return;
|
||||
}
|
||||
if (isRetryTimeout(now, MAX_COMMIT_RETRY_TIMEOUT.toMillis(), committingSession.getBeginTime())) {
|
||||
// Prevent thread safety issues
|
||||
SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(committingSession);
|
||||
LOGGER.error("Global transaction commit retry timeout and has removed [{}]",
|
||||
committingSession.getXid());
|
||||
|
||||
// commit retry timeout event
|
||||
SessionHelper.endCommitFailed(committingSession, true, true);
|
||||
|
||||
// The function of this 'return' is 'continue'.
|
||||
return;
|
||||
}
|
||||
committingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
core.doGlobalCommit(committingSession, true);
|
||||
}
|
||||
catch (TransactionException ex) {
|
||||
LOGGER.info("Failed to retry committing [{}] {} {}", committingSession.getXid(), ex.getCode(),
|
||||
ex.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle async committing.
|
||||
*/
|
||||
protected void handleAsyncCommitting() {
|
||||
SessionCondition sessionCondition = new SessionCondition(GlobalStatus.AsyncCommitting);
|
||||
Collection<GlobalSession> asyncCommittingSessions = SessionHolder.getAsyncCommittingSessionManager()
|
||||
.findGlobalSessions(sessionCondition);
|
||||
if (CollectionUtils.isEmpty(asyncCommittingSessions)) {
|
||||
return;
|
||||
}
|
||||
SessionHelper.forEach(asyncCommittingSessions, asyncCommittingSession -> {
|
||||
try {
|
||||
asyncCommittingSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
core.doGlobalCommit(asyncCommittingSession, true);
|
||||
}
|
||||
catch (TransactionException ex) {
|
||||
LOGGER.error("Failed to async committing [{}] {} {}", asyncCommittingSession.getXid(), ex.getCode(),
|
||||
ex.getMessage(), ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo log delete.
|
||||
*/
|
||||
protected void undoLogDelete() {
|
||||
Map<String, Channel> rmChannels = ChannelManager.getRmChannels();
|
||||
if (rmChannels == null || rmChannels.isEmpty()) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("no active rm channels to delete undo log");
|
||||
}
|
||||
return;
|
||||
}
|
||||
short saveDays = CONFIG.getShort(ConfigurationKeys.TRANSACTION_UNDO_LOG_SAVE_DAYS,
|
||||
UndoLogDeleteRequest.DEFAULT_SAVE_DAYS);
|
||||
for (Map.Entry<String, Channel> channelEntry : rmChannels.entrySet()) {
|
||||
String resourceId = channelEntry.getKey();
|
||||
UndoLogDeleteRequest deleteRequest = new UndoLogDeleteRequest();
|
||||
deleteRequest.setResourceId(resourceId);
|
||||
deleteRequest.setSaveDays(saveDays > 0 ? saveDays : UndoLogDeleteRequest.DEFAULT_SAVE_DAYS);
|
||||
try {
|
||||
remotingServer.sendAsyncRequest(channelEntry.getValue(), deleteRequest);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("Failed to async delete undo log resourceId = {}, exception: {}", resourceId,
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRetryTimeout(long now, long timeout, long beginTime) {
|
||||
return timeout >= ALWAYS_RETRY_BOUNDARY && now - beginTime > timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*/
|
||||
public void init() {
|
||||
retryRollbacking.scheduleAtFixedRate(
|
||||
() -> SessionHolder.distributedLockAndExecute(RETRY_ROLLBACKING, this::handleRetryRollbacking), 0,
|
||||
ROLLBACKING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
|
||||
|
||||
retryCommitting.scheduleAtFixedRate(
|
||||
() -> SessionHolder.distributedLockAndExecute(RETRY_COMMITTING, this::handleRetryCommitting), 0,
|
||||
COMMITTING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
|
||||
|
||||
asyncCommitting.scheduleAtFixedRate(
|
||||
() -> SessionHolder.distributedLockAndExecute(ASYNC_COMMITTING, this::handleAsyncCommitting), 0,
|
||||
ASYNC_COMMITTING_RETRY_PERIOD, TimeUnit.MILLISECONDS);
|
||||
|
||||
timeoutCheck.scheduleAtFixedRate(
|
||||
() -> SessionHolder.distributedLockAndExecute(TX_TIMEOUT_CHECK, this::timeoutCheck), 0,
|
||||
TIMEOUT_RETRY_PERIOD, TimeUnit.MILLISECONDS);
|
||||
|
||||
undoLogDelete.scheduleAtFixedRate(
|
||||
() -> SessionHolder.distributedLockAndExecute(UNDOLOG_DELETE, this::undoLogDelete),
|
||||
UNDO_LOG_DELAY_DELETE_PERIOD, UNDO_LOG_DELETE_PERIOD, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractResultMessage onRequest(AbstractMessage request, RpcContext context) {
|
||||
if (!(request instanceof AbstractTransactionRequestToTC)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
AbstractTransactionRequestToTC transactionRequest = (AbstractTransactionRequestToTC) request;
|
||||
transactionRequest.setTCInboundHandler(this);
|
||||
|
||||
return transactionRequest.handle(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(AbstractResultMessage response, RpcContext context) {
|
||||
if (!(response instanceof AbstractTransactionResponse)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// 1. first shutdown timed task
|
||||
retryRollbacking.shutdown();
|
||||
retryCommitting.shutdown();
|
||||
asyncCommitting.shutdown();
|
||||
timeoutCheck.shutdown();
|
||||
undoLogDelete.shutdown();
|
||||
branchRemoveExecutor.shutdown();
|
||||
try {
|
||||
retryRollbacking.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
|
||||
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);
|
||||
undoLogDelete.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
|
||||
branchRemoveExecutor.awaitTermination(TIMED_TASK_SHUTDOWN_MAX_WAIT_MILLS, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (InterruptedException ignore) {
|
||||
|
||||
}
|
||||
// 2. second close netty flow
|
||||
if (remotingServer instanceof NettyRemotingServer) {
|
||||
((NettyRemotingServer) remotingServer).destroy();
|
||||
}
|
||||
// 3. third destroy SessionHolder
|
||||
SessionHolder.destroy();
|
||||
instance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* only used for mock test
|
||||
* @param remotingServer
|
||||
*/
|
||||
public void setRemotingServer(RemotingServer remotingServer) {
|
||||
this.remotingServer = remotingServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* the task to remove branchSession
|
||||
*/
|
||||
static class BranchRemoveTask implements Runnable {
|
||||
|
||||
/**
|
||||
* the globalSession
|
||||
*/
|
||||
private final GlobalSession globalSession;
|
||||
|
||||
/**
|
||||
* the branchSession
|
||||
*/
|
||||
private final BranchSession branchSession;
|
||||
|
||||
/**
|
||||
* If you use this construct, the task will remove the branchSession provided by
|
||||
* the parameter
|
||||
* @param globalSession the globalSession
|
||||
*/
|
||||
public BranchRemoveTask(GlobalSession globalSession, BranchSession branchSession) {
|
||||
this.globalSession = globalSession;
|
||||
this.branchSession = branchSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you use this construct, the task will remove all branchSession
|
||||
* @param globalSession the globalSession
|
||||
*/
|
||||
public BranchRemoveTask(GlobalSession globalSession) {
|
||||
this.globalSession = globalSession;
|
||||
this.branchSession = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (globalSession == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_XID, globalSession.getXid());
|
||||
if (branchSession != null) {
|
||||
doRemove(branchSession);
|
||||
}
|
||||
else {
|
||||
globalSession.getSortedBranches().forEach(this::doRemove);
|
||||
}
|
||||
}
|
||||
catch (Exception unKnowException) {
|
||||
LOGGER.error("Asynchronous delete branchSession error, xid = {}", globalSession.getXid(),
|
||||
unKnowException);
|
||||
}
|
||||
finally {
|
||||
MDC.remove(RootContext.MDC_KEY_XID);
|
||||
}
|
||||
}
|
||||
|
||||
private void doRemove(BranchSession bt) {
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(bt.getBranchId()));
|
||||
globalSession.removeBranch(bt);
|
||||
LOGGER.info("Asynchronous delete branchSession successfully, xid = {}, branchId = {}",
|
||||
globalSession.getXid(), bt.getBranchId());
|
||||
}
|
||||
catch (TransactionException transactionException) {
|
||||
LOGGER.error("Asynchronous delete branchSession error, xid = {}, branchId = {}", globalSession.getXid(),
|
||||
bt.getBranchId(), transactionException);
|
||||
}
|
||||
finally {
|
||||
MDC.remove(RootContext.MDC_KEY_BRANCH_ID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-424
@@ -1,424 +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.coordinator;
|
||||
|
||||
import io.seata.common.DefaultValues;
|
||||
import io.seata.common.exception.NotSupportYetException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.context.RootContext;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.logger.StackTraceLogger;
|
||||
import io.seata.core.model.BranchStatus;
|
||||
import io.seata.core.model.BranchType;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.rpc.RemotingServer;
|
||||
import io.seata.server.metrics.MetricsPublisher;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
import io.seata.server.session.SessionHelper;
|
||||
import io.seata.server.session.SessionHolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static io.seata.core.constants.ConfigurationKeys.XAER_NOTA_RETRY_TIMEOUT;
|
||||
import static io.seata.server.session.BranchSessionHandler.CONTINUE;
|
||||
|
||||
/**
|
||||
* The type Default core.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class DefaultCore implements Core {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCore.class);
|
||||
|
||||
private static final int RETRY_XAER_NOTA_TIMEOUT = ConfigurationFactory.getInstance()
|
||||
.getInt(XAER_NOTA_RETRY_TIMEOUT, DefaultValues.DEFAULT_XAER_NOTA_RETRY_TIMEOUT);
|
||||
|
||||
private static Map<BranchType, AbstractCore> coreMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* get the Default core.
|
||||
* @param remotingServer the remoting server
|
||||
*/
|
||||
public DefaultCore(RemotingServer remotingServer) {
|
||||
List<AbstractCore> allCore = EnhancedServiceLoader.loadAll(AbstractCore.class,
|
||||
new Class[] { RemotingServer.class }, new Object[] { remotingServer });
|
||||
if (CollectionUtils.isNotEmpty(allCore)) {
|
||||
for (AbstractCore core : allCore) {
|
||||
coreMap.put(core.getHandleBranchType(), core);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get core
|
||||
* @param branchType the branchType
|
||||
* @return the core
|
||||
*/
|
||||
public AbstractCore getCore(BranchType branchType) {
|
||||
AbstractCore core = coreMap.get(branchType);
|
||||
if (core == null) {
|
||||
throw new NotSupportYetException("unsupported type:" + branchType.name());
|
||||
}
|
||||
return core;
|
||||
}
|
||||
|
||||
/**
|
||||
* only for mock
|
||||
* @param branchType the branchType
|
||||
* @param core the core
|
||||
*/
|
||||
public void mockCore(BranchType branchType, AbstractCore core) {
|
||||
coreMap.put(branchType, core);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
return getCore(branchType).branchRegister(branchType, resourceId, clientId, xid, applicationData, lockKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
getCore(branchType).branchReport(branchType, xid, branchId, status, applicationData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return getCore(branchType).lockQuery(branchType, resourceId, xid, lockKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchCommit(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchRollback(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
GlobalSession session = GlobalSession.createGlobalSession(applicationId, transactionServiceGroup, name,
|
||||
timeout);
|
||||
MDC.put(RootContext.MDC_KEY_XID, session.getXid());
|
||||
session.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
|
||||
session.begin();
|
||||
|
||||
// transaction start event
|
||||
MetricsPublisher.postSessionDoingEvent(session, false);
|
||||
|
||||
return session.getXid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
|
||||
if (globalSession.isTimeout()) {
|
||||
LOGGER.info("TC detected timeout, xid = {}", globalSession.getXid());
|
||||
return GlobalStatus.TimeoutRollbacking;
|
||||
}
|
||||
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
|
||||
boolean shouldCommit = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
// Highlight: Firstly, close the session, then no more branch can be
|
||||
// registered.
|
||||
globalSession.closeAndClean();
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.Committed, false, false);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Committing);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (shouldCommit) {
|
||||
boolean success = doGlobalCommit(globalSession, false);
|
||||
// If successful and all remaining branches can be committed asynchronously,
|
||||
// do async commit.
|
||||
if (success && globalSession.hasBranch() && globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
return GlobalStatus.Committed;
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus() == GlobalStatus.AsyncCommitting ? GlobalStatus.Committed
|
||||
: globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start committing event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalCommit(globalSession, retrying);
|
||||
}
|
||||
else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getSortedBranches(), branchSession -> {
|
||||
// if not retrying, skip the canBeCommittedAsync branches
|
||||
if (!retrying && branchSession.canBeCommittedAsync()) {
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
BranchStatus currentStatus = branchSession.getStatus();
|
||||
if (currentStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = getCore(branchSession.getBranchType()).branchCommit(globalSession,
|
||||
branchSession);
|
||||
if (isXaerNotaTimeout(globalSession, branchStatus)) {
|
||||
LOGGER.info("Commit branch XAER_NOTA retry timeout, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Committed;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Committed:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
case PhaseTwo_CommitFailed_Unretryable:
|
||||
// not at branch
|
||||
SessionHelper.endCommitFailed(globalSession, retrying);
|
||||
LOGGER.error(
|
||||
"Committing global transaction[{}] finally failed, caused by branch transaction[{}] commit failed.",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
|
||||
default:
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
return false;
|
||||
}
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.error("Committing branch transaction[{}], status:{} and will retry later",
|
||||
branchSession.getBranchId(), branchStatus);
|
||||
return CONTINUE;
|
||||
}
|
||||
else {
|
||||
LOGGER.error(
|
||||
"Committing global transaction[{}] failed, caused by branch transaction[{}] commit failed, will retry later.",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex, "Committing branch transaction exception: {}",
|
||||
new String[] { branchSession.toString() });
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
}
|
||||
return CONTINUE;
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
// If has branch and not all remaining branches can be committed
|
||||
// asynchronously,
|
||||
// do print log and return false
|
||||
if (globalSession.hasBranch() && !globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.info("Committing global transaction is NOT done, xid = {}.", globalSession.getXid());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if it succeeds and there is no branch, retrying=true is the asynchronous state
|
||||
// when retrying. EndCommitted is
|
||||
// executed to improve concurrency performance, and the global transaction ends..
|
||||
if (success && globalSession.getBranchSessions().isEmpty()) {
|
||||
if (!retrying) {
|
||||
// contains not AT branch
|
||||
globalSession.setStatus(GlobalStatus.Committed);
|
||||
}
|
||||
SessionHelper.endCommitted(globalSession, retrying);
|
||||
LOGGER.info("Committing global transaction is successfully done, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
boolean shouldRollBack = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSession.close(); // Highlight: Firstly, close the session, then no more
|
||||
// branch can be registered.
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Rollbacking);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!shouldRollBack) {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
|
||||
boolean rollbackSuccess = doGlobalRollback(globalSession, false);
|
||||
return rollbackSuccess ? GlobalStatus.Rollbacked : globalSession.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start rollback event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalRollback(globalSession, retrying);
|
||||
}
|
||||
else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getReverseSortedBranches(), branchSession -> {
|
||||
BranchStatus currentBranchStatus = branchSession.getStatus();
|
||||
if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = branchRollback(globalSession, branchSession);
|
||||
if (isXaerNotaTimeout(globalSession, branchStatus)) {
|
||||
LOGGER.info("Rollback branch XAER_NOTA retry timeout, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Rollbacked;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Rollbacked:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
LOGGER.info("Rollback branch transaction successfully, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return CONTINUE;
|
||||
case PhaseTwo_RollbackFailed_Unretryable:
|
||||
SessionHelper.endRollbackFailed(globalSession, retrying);
|
||||
LOGGER.info("Rollback branch transaction fail and stop retry, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
default:
|
||||
LOGGER.info("Rollback branch transaction fail and will retry, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex,
|
||||
"Rollback branch transaction exception, xid = {} branchId = {} exception = {}",
|
||||
new String[] { globalSession.getXid(), String.valueOf(branchSession.getBranchId()),
|
||||
ex.getMessage() });
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// In db mode, lock and branch data residual problems may occur.
|
||||
// Therefore, execution needs to be delayed here and cannot be executed
|
||||
// synchronously.
|
||||
if (success) {
|
||||
SessionHelper.endRollbacked(globalSession, retrying);
|
||||
LOGGER.info("Rollback global transaction successfully, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, false);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return globalStatus;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
doGlobalReport(globalSession, xid, globalStatus);
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus)
|
||||
throws TransactionException {
|
||||
if (globalSession.isSaga()) {
|
||||
getCore(BranchType.SAGA).doGlobalReport(globalSession, xid, globalStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isXaerNotaTimeout(GlobalSession globalSession, BranchStatus branchStatus) {
|
||||
if (BranchStatus.PhaseTwo_CommitFailed_XAER_NOTA_Retryable.equals(branchStatus)
|
||||
|| BranchStatus.PhaseTwo_RollbackFailed_XAER_NOTA_Retryable.equals(branchStatus)) {
|
||||
return System.currentTimeMillis() > globalSession.getBeginTime() + globalSession.getTimeout()
|
||||
+ Math.max(RETRY_XAER_NOTA_TIMEOUT, globalSession.getTimeout());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-29
@@ -1,29 +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.coordinator;
|
||||
|
||||
import io.seata.core.model.ResourceManagerOutbound;
|
||||
import io.seata.core.model.TransactionManager;
|
||||
|
||||
/**
|
||||
* receive inbound request from RM or TM.
|
||||
*
|
||||
* @author zhangchenghui.dev@gmail.com
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface TransactionCoordinatorInbound extends ResourceManagerOutbound, TransactionManager {
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +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.coordinator;
|
||||
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.model.BranchStatus;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
|
||||
/**
|
||||
* send outbound request to RM.
|
||||
*
|
||||
* @author zhangchenghui.dev@gmail.com
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public interface TransactionCoordinatorOutbound {
|
||||
|
||||
/**
|
||||
* Commit a branch transaction.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after committing.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with
|
||||
* TransactionException and thrown out.
|
||||
*/
|
||||
BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Rollback a branch transaction.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after rollbacking.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with
|
||||
* TransactionException and thrown out.
|
||||
*/
|
||||
BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
}
|
||||
-103
@@ -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.env;
|
||||
|
||||
import io.seata.common.util.NumberUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
|
||||
import static io.seata.core.constants.ConfigurationKeys.ENV_SEATA_PORT_KEY;
|
||||
|
||||
/**
|
||||
* @author xingfudeshi@gmail.com
|
||||
* @author wang.liang
|
||||
*/
|
||||
public class ContainerHelper {
|
||||
|
||||
private static final String C_GROUP_PATH = "/proc/1/cgroup";
|
||||
|
||||
private static final String DOCKER_PATH = "/docker";
|
||||
|
||||
private static final String KUBEPODS_PATH = "/kubepods";
|
||||
|
||||
private static final String ENV_SYSTEM_KEY = "SEATA_ENV";
|
||||
|
||||
private static final String ENV_SEATA_IP_KEY = "SEATA_IP";
|
||||
|
||||
private static final String ENV_SERVER_NODE_KEY = "SERVER_NODE";
|
||||
|
||||
private static final String ENV_STORE_MODE_KEY = "STORE_MODE";
|
||||
|
||||
private static final String ENV_LOCK_STORE_MODE_KEY = "LOCK_STORE_MODE";
|
||||
|
||||
private static final String ENV_SESSION_STORE_MODE_KEY = "SESSION_STORE_MODE";
|
||||
|
||||
/**
|
||||
* Gets env from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getEnv() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SYSTEM_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets host from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getHost() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SEATA_IP_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets port from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static int getPort() {
|
||||
return NumberUtils.toInt(System.getenv(ENV_SEATA_PORT_KEY), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server node from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static Long getServerNode() {
|
||||
return NumberUtils.toLong(System.getenv(ENV_SERVER_NODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets session store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getSessionStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SESSION_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getLockStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_LOCK_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
}
|
||||
-134
@@ -1,134 +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.env;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.common.util.MapUtil;
|
||||
import io.seata.common.util.NumberUtils;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author wang.liang
|
||||
*/
|
||||
public class PortHelper {
|
||||
|
||||
public static int getPortFromEnvOrStartup(String[] args) {
|
||||
int port = 0;
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
port = NumberUtils.toInt(args[i + 1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* get config from configFile -Dspring.config.location >
|
||||
* classpath:application.properties > classpath:application.yml
|
||||
* @return the port
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public static int getPortFromConfigFile() throws IOException {
|
||||
|
||||
int port = 8080;
|
||||
File configFile = null;
|
||||
File startupConfigFile = getConfigFromStartup();
|
||||
if (null != startupConfigFile) {
|
||||
configFile = startupConfigFile;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
File propertiesFile = ResourceUtils.getFile("classpath:application.properties");
|
||||
configFile = propertiesFile;
|
||||
}
|
||||
catch (FileNotFoundException exx) {
|
||||
File ymlFile = ResourceUtils.getFile("classpath:application.yml");
|
||||
configFile = ymlFile;
|
||||
}
|
||||
}
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(configFile);
|
||||
String fileName = configFile.getName();
|
||||
String portNum = null;
|
||||
if (fileName.endsWith("yml")) {
|
||||
Map<String, Object> yamlMap = new Yaml().load(inputStream);
|
||||
Map<String, Object> configMap = MapUtil.getFlattenedMap(yamlMap);
|
||||
if (CollectionUtils.isNotEmpty(configMap)) {
|
||||
Object serverPort = configMap.get("server.port");
|
||||
if (null != serverPort) {
|
||||
portNum = serverPort.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
portNum = properties.getProperty("server.port");
|
||||
}
|
||||
if (null != portNum) {
|
||||
try {
|
||||
port = Integer.parseInt(portNum);
|
||||
}
|
||||
catch (NumberFormatException exx) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (null != inputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
return port;
|
||||
|
||||
}
|
||||
|
||||
private static File getConfigFromStartup() {
|
||||
|
||||
String configLocation = System.getProperty("spring.config.location");
|
||||
if (StringUtils.isNotBlank(configLocation)) {
|
||||
try {
|
||||
File configFile = ResourceUtils.getFile(configLocation);
|
||||
if (!configFile.isFile()) {
|
||||
return null;
|
||||
}
|
||||
String fileName = configFile.getName();
|
||||
if (!(fileName.endsWith("yml") || fileName.endsWith("properties"))) {
|
||||
return null;
|
||||
}
|
||||
return configFile;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +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.event;
|
||||
|
||||
import io.seata.core.event.EventBus;
|
||||
import io.seata.core.event.GuavaEventBus;
|
||||
|
||||
/**
|
||||
* Manager hold the singleton event bus instance.
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class EventBusManager {
|
||||
|
||||
private static class SingletonHolder {
|
||||
|
||||
private static EventBus INSTANCE = new GuavaEventBus("tc", true);
|
||||
|
||||
}
|
||||
|
||||
public static EventBus get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
-196
@@ -1,196 +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.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.core.model.LockStatus;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The type Abstract lock manager.
|
||||
*
|
||||
* @author zhangsen
|
||||
*/
|
||||
public abstract class AbstractLockManager implements LockManager {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockManager.class);
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession) throws TransactionException {
|
||||
return acquireLock(branchSession, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock)
|
||||
throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
String lockKey = branchSession.getLockKey();
|
||||
if (StringUtils.isNullOrEmpty(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
// get locks of branch
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
return getLocker(branchSession).acquireLock(locks, autoCommit, skipCheckLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
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 {
|
||||
if (StringUtils.isBlank(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(lockKey, resourceId, xid);
|
||||
try {
|
||||
return getLocker().isLockable(locks);
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("isLockable error, xid:{} resourceId:{}, lockKey:{}", xid, resourceId, 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 abstract Locker getLocker(BranchSession branchSession);
|
||||
|
||||
@Override
|
||||
public List<RowLock> collectRowLocks(BranchSession branchSession) {
|
||||
if (branchSession == null || StringUtils.isBlank(branchSession.getLockKey())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
String lockKey = branchSession.getLockKey();
|
||||
String resourceId = branchSession.getResourceId();
|
||||
String xid = branchSession.getXid();
|
||||
long transactionId = branchSession.getTransactionId();
|
||||
long branchId = branchSession.getBranchId();
|
||||
|
||||
return collectRowLocks(lockKey, resourceId, xid, transactionId, branchId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect row locks list.
|
||||
* @param lockKey the lock key
|
||||
* @param resourceId the resource id
|
||||
* @param xid the xid
|
||||
* @return the list
|
||||
*/
|
||||
protected List<RowLock> 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<RowLock> collectRowLocks(String lockKey, String resourceId, String xid, Long transactionId,
|
||||
Long branchID) {
|
||||
List<RowLock> 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
this.getLocker().updateLockStatus(xid, lockStatus);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,100 +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.core.exception.TransactionException;
|
||||
import io.seata.core.lock.RowLock;
|
||||
import io.seata.core.model.LockStatus;
|
||||
import io.seata.server.session.BranchSession;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The interface Lock manager.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public interface LockManager {
|
||||
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @param autoCommit the auto commit
|
||||
* @param skipCheckLock whether skip check lock or not
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock)
|
||||
throws TransactionException;
|
||||
|
||||
/**
|
||||
* Un lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseLock(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Un lock boolean.
|
||||
* @param globalSession the global session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Is lockable boolean.
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Clean all locks.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void cleanAllLocks() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Collect row locks list.`
|
||||
* @param branchSession the branch session
|
||||
* @return the list
|
||||
*/
|
||||
List<RowLock> collectRowLocks(BranchSession branchSession);
|
||||
|
||||
/**
|
||||
* update lock status.
|
||||
* @param xid the xid
|
||||
* @param lockStatus the lock status
|
||||
* @throws TransactionException the transaction exception
|
||||
*
|
||||
*/
|
||||
void updateLockStatus(String xid, LockStatus lockStatus) throws TransactionException;
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +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.server.store.StoreConfig;
|
||||
import io.seata.server.store.StoreConfig.LockMode;
|
||||
|
||||
/**
|
||||
* The type Lock manager factory.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class LockerManagerFactory {
|
||||
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* the lock manager
|
||||
*/
|
||||
private static volatile LockManager LOCK_MANAGER;
|
||||
|
||||
/**
|
||||
* Get lock manager.
|
||||
* @return the lock manager
|
||||
*/
|
||||
public static LockManager getLockManager() {
|
||||
if (LOCK_MANAGER == null) {
|
||||
init();
|
||||
}
|
||||
return LOCK_MANAGER;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
init(null);
|
||||
}
|
||||
|
||||
public static void init(LockMode lockMode) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
synchronized (LockerManagerFactory.class) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
if (null == lockMode) {
|
||||
lockMode = StoreConfig.getLockMode();
|
||||
}
|
||||
// if not exist the lock mode, throw exception
|
||||
if (null != StoreConfig.StoreMode.get(lockMode.name())) {
|
||||
LOCK_MANAGER = EnhancedServiceLoader.load(LockManager.class, lockMode.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-71
@@ -1,71 +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.distributed;
|
||||
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.loader.EnhancedServiceNotFoundException;
|
||||
import io.seata.core.store.DefaultDistributedLocker;
|
||||
import io.seata.core.store.DistributedLocker;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Distributed locker factory
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class DistributedLockerFactory {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockerFactory.class);
|
||||
|
||||
private static volatile DistributedLocker DISTRIBUTED_LOCKER = null;
|
||||
|
||||
/**
|
||||
* Get the distributed locker by lockerType
|
||||
* @param lockerType the locker type
|
||||
* @return the distributed locker
|
||||
*/
|
||||
public static DistributedLocker getDistributedLocker(String lockerType) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
synchronized (DistributedLocker.class) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
DistributedLocker distributedLocker = null;
|
||||
try {
|
||||
if (!"file".equals(lockerType)) {
|
||||
distributedLocker = EnhancedServiceLoader.load(DistributedLocker.class, lockerType);
|
||||
}
|
||||
}
|
||||
catch (EnhancedServiceNotFoundException ex) {
|
||||
LOGGER.error("Get distributed locker failed: {}", ex.getMessage(), ex);
|
||||
}
|
||||
if (distributedLocker == null) {
|
||||
distributedLocker = new DefaultDistributedLocker();
|
||||
}
|
||||
DISTRIBUTED_LOCKER = distributedLocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DISTRIBUTED_LOCKER;
|
||||
}
|
||||
|
||||
public static void cleanLocker() {
|
||||
DISTRIBUTED_LOCKER = null;
|
||||
}
|
||||
|
||||
}
|
||||
-76
@@ -1,76 +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.logging.listener;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import ch.qos.logback.classic.spi.LoggerContextListener;
|
||||
import ch.qos.logback.core.Context;
|
||||
import ch.qos.logback.core.spi.ContextAwareBase;
|
||||
import ch.qos.logback.core.spi.LifeCycle;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
|
||||
/**
|
||||
* @author wang.liang
|
||||
*/
|
||||
public class SystemPropertyLoggerContextListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
context.putProperty("RPC_PORT", System.getProperty(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL));
|
||||
|
||||
started = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResetResistant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReset(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLevelChange(Logger logger, Level level) {
|
||||
}
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +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.logging.logback;
|
||||
|
||||
import ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter;
|
||||
import ch.qos.logback.classic.spi.IThrowableProxy;
|
||||
import ch.qos.logback.core.CoreConstants;
|
||||
|
||||
/**
|
||||
* {@link ExtendedThrowableProxyConverter} that adds some additional whitespace around the
|
||||
* stack trace. Copied from spring-boot-xxx.jar by wang.liang
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ExtendedWhitespaceThrowableProxyConverter extends ExtendedThrowableProxyConverter {
|
||||
|
||||
@Override
|
||||
protected String throwableProxyToString(IThrowableProxy tp) {
|
||||
return "==>" + CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp) + "<=="
|
||||
+ CoreConstants.LINE_SEPARATOR + CoreConstants.LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
}
|
||||
-45
@@ -1,45 +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.logging.logback.appender;
|
||||
|
||||
import net.logstash.logback.composite.JsonProvider;
|
||||
import net.logstash.logback.composite.JsonProviders;
|
||||
import net.logstash.logback.encoder.LogstashEncoder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The type Enhanced logstash encoder
|
||||
*
|
||||
* @author wang.liang
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class EnhancedLogstashEncoder extends LogstashEncoder {
|
||||
|
||||
/**
|
||||
* set exclude provider
|
||||
* @param excludedProviderClassName the excluded provider class name
|
||||
*/
|
||||
public void setExcludeProvider(String excludedProviderClassName) {
|
||||
JsonProviders<?> providers = getFormatter().getProviders();
|
||||
for (JsonProvider<?> provider : new ArrayList<>(providers.getProviders())) {
|
||||
if (provider.getClass().getName().equals(excludedProviderClassName)) {
|
||||
providers.removeProvider((JsonProvider) provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-103
@@ -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.metrics;
|
||||
|
||||
import io.seata.metrics.Id;
|
||||
import io.seata.metrics.IdConstants;
|
||||
|
||||
/**
|
||||
* Constants for meter id in tc
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface MeterIdConstants {
|
||||
|
||||
Id COUNTER_ACTIVE = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ACTIVE);
|
||||
|
||||
Id COUNTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id COUNTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id COUNTER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id COUNTER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
Id SUMMARY_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id SUMMARY_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id SUMMARY_FAILED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
|
||||
Id SUMMARY_TWO_PHASE_TIMEOUT = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_TWO_PHASE_TIMEOUT);
|
||||
|
||||
Id SUMMARY_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id SUMMARY_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
Id TIMER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id TIMER_ROLLBACK = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id TIMER_FAILED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
|
||||
Id TIMER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id TIMER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
}
|
||||
-70
@@ -1,70 +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.metrics;
|
||||
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import io.seata.metrics.exporter.Exporter;
|
||||
import io.seata.metrics.exporter.ExporterFactory;
|
||||
import io.seata.metrics.registry.Registry;
|
||||
import io.seata.metrics.registry.RegistryFactory;
|
||||
import io.seata.server.event.EventBusManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_METRICS_ENABLED;
|
||||
|
||||
/**
|
||||
* Metrics manager for init
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class MetricsManager {
|
||||
|
||||
private static class SingletonHolder {
|
||||
|
||||
private static MetricsManager INSTANCE = new MetricsManager();
|
||||
|
||||
}
|
||||
|
||||
public static final MetricsManager get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private Registry registry;
|
||||
|
||||
public Registry getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
boolean enabled = ConfigurationFactory.getInstance().getBoolean(
|
||||
ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_ENABLED, DEFAULT_METRICS_ENABLED);
|
||||
if (enabled) {
|
||||
registry = RegistryFactory.getInstance();
|
||||
if (registry != null) {
|
||||
List<Exporter> exporters = ExporterFactory.getInstanceList();
|
||||
// only at least one metrics exporter implement had imported in pom then
|
||||
// need register MetricsSubscriber
|
||||
if (exporters.size() != 0) {
|
||||
exporters.forEach(exporter -> exporter.setRegistry(registry));
|
||||
EventBusManager.get().register(new MetricsSubscriber(registry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-96
@@ -1,96 +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.metrics;
|
||||
|
||||
import io.seata.core.event.EventBus;
|
||||
import io.seata.core.event.GlobalTransactionEvent;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.server.event.EventBusManager;
|
||||
import io.seata.server.session.GlobalSession;
|
||||
|
||||
/**
|
||||
* The type Metrics publisher.
|
||||
*
|
||||
* @author slievrly
|
||||
*/
|
||||
public class MetricsPublisher {
|
||||
|
||||
private static final EventBus EVENT_BUS = EventBusManager.get();
|
||||
|
||||
/**
|
||||
* post end event
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, globalSession.getStatus(), retryGlobal, retryBranch);
|
||||
}
|
||||
|
||||
/**
|
||||
* post end event (force specified state)
|
||||
* @param globalSession the global session
|
||||
* @param status the global status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, GlobalStatus status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, status.name(), retryGlobal, globalSession.getBeginTime(), retryBranch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session done event.
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param beginTime the begin time
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, String status, boolean retryGlobal,
|
||||
long beginTime, boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), beginTime, System.currentTimeMillis(), status, retryGlobal,
|
||||
retryBranch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session doing event.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, boolean retryGlobal) {
|
||||
postSessionDoingEvent(globalSession, globalSession.getStatus().name(), retryGlobal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session doing event.
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, String status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), globalSession.getBeginTime(), null, status, retryGlobal,
|
||||
retryBranch));
|
||||
}
|
||||
|
||||
}
|
||||
-196
@@ -1,196 +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.metrics;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import io.seata.core.event.GlobalTransactionEvent;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.metrics.registry.Registry;
|
||||
import io.seata.server.event.EventBusManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static io.seata.metrics.IdConstants.*;
|
||||
|
||||
/**
|
||||
* Event subscriber for metrics
|
||||
*
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class MetricsSubscriber {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MetricsSubscriber.class);
|
||||
|
||||
private final Registry registry;
|
||||
|
||||
private final Map<String, Consumer<GlobalTransactionEvent>> consumers;
|
||||
|
||||
public MetricsSubscriber(Registry registry) {
|
||||
this.registry = registry;
|
||||
consumers = new HashMap<>();
|
||||
consumers.put(GlobalStatus.Begin.name(), this::processGlobalStatusBegin);
|
||||
consumers.put(GlobalStatus.Committed.name(), this::processGlobalStatusCommitted);
|
||||
consumers.put(GlobalStatus.Rollbacked.name(), this::processGlobalStatusRollbacked);
|
||||
|
||||
consumers.put(GlobalStatus.CommitFailed.name(), this::processGlobalStatusCommitFailed);
|
||||
consumers.put(GlobalStatus.RollbackFailed.name(), this::processGlobalStatusRollbackFailed);
|
||||
consumers.put(GlobalStatus.TimeoutRollbacked.name(), this::processGlobalStatusTimeoutRollbacked);
|
||||
consumers.put(GlobalStatus.TimeoutRollbackFailed.name(), this::processGlobalStatusTimeoutRollbackFailed);
|
||||
|
||||
consumers.put(GlobalStatus.CommitRetryTimeout.name(), this::processGlobalStatusCommitRetryTimeout);
|
||||
consumers.put(GlobalStatus.RollbackRetryTimeout.name(), this::processGlobalStatusTimeoutRollbackRetryTimeout);
|
||||
|
||||
consumers.put(STATUS_VALUE_AFTER_COMMITTED_KEY, this::processAfterGlobalCommitted);
|
||||
consumers.put(STATUS_VALUE_AFTER_ROLLBACKED_KEY, this::processAfterGlobalRollbacked);
|
||||
}
|
||||
|
||||
private void processGlobalStatusBegin(GlobalTransactionEvent event) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("accept new event,xid:{},event:{}", event.getId(), event);
|
||||
for (Object object : EventBusManager.get().getSubscribers()) {
|
||||
LOGGER.debug("subscribe:{},threadName:{}", object.toString(), Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processGlobalStatusRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_ROLLBACK.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processAfterGlobalRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processAfterGlobalCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbacked(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbackRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
|
||||
private void decreaseActive(GlobalTransactionEvent event) {
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).decrease(1);
|
||||
}
|
||||
|
||||
private void reportFailed(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_FAILED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_FAILED.withTag(APP_ID_KEY, event.getApplicationId()).withTag(GROUP_KEY,
|
||||
event.getGroup())).record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void reportTwoPhaseTimeout(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void recordGlobalTransactionEventForMetrics(GlobalTransactionEvent event) {
|
||||
if (registry != null && consumers.containsKey(event.getStatus())) {
|
||||
consumers.get(event.getStatus()).accept(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.getClass().getName().equals(obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* PMD check SuppressWarnings("checkstyle:EqualsHashCode")
|
||||
* @return the hash code
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
-204
@@ -1,204 +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;
|
||||
|
||||
import io.seata.core.exception.BranchTransactionException;
|
||||
import io.seata.core.exception.GlobalTransactionException;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.exception.TransactionExceptionCode;
|
||||
import io.seata.core.model.BranchStatus;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.model.LockStatus;
|
||||
import io.seata.server.store.SessionStorable;
|
||||
import io.seata.server.store.TransactionStoreManager;
|
||||
import io.seata.server.store.TransactionStoreManager.LogOperation;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The type Abstract session manager.
|
||||
*/
|
||||
public abstract class AbstractSessionManager implements SessionManager, SessionLifecycleListener {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractSessionManager.class);
|
||||
|
||||
/**
|
||||
* The Transaction store manager.
|
||||
*/
|
||||
protected TransactionStoreManager transactionStoreManager;
|
||||
|
||||
/**
|
||||
* The Name.
|
||||
*/
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
*/
|
||||
public AbstractSessionManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
* @param name the name
|
||||
*/
|
||||
public AbstractSessionManager(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_ADD);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_UPDATE);
|
||||
}
|
||||
if (GlobalStatus.Rollbacking == status) {
|
||||
session.getBranchSessions().forEach(i -> i.setLockStatus(LockStatus.Rollbacking));
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession session, BranchSession branchSession) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_ADD);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_ADD, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_UPDATE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_UPDATE, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_REMOVE, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBegin(GlobalSession globalSession) throws TransactionException {
|
||||
addGlobalSession(globalSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException {
|
||||
updateGlobalSessionStatus(globalSession, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
updateBranchSessionStatus(branchSession, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
addBranchSession(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
removeBranchSession(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(GlobalSession globalSession) throws TransactionException {
|
||||
globalSession.setActive(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccessEnd(GlobalSession globalSession) throws TransactionException {
|
||||
removeGlobalSession(globalSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailEnd(GlobalSession globalSession) throws TransactionException {
|
||||
LOGGER.info("xid:{} fail end, transaction:{}", globalSession.getXid(), globalSession.toString());
|
||||
}
|
||||
|
||||
private void writeSession(LogOperation logOperation, SessionStorable sessionStorable) throws TransactionException {
|
||||
if (!transactionStoreManager.writeSession(logOperation, sessionStorable)) {
|
||||
if (LogOperation.GLOBAL_ADD.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store global session");
|
||||
}
|
||||
else if (LogOperation.GLOBAL_UPDATE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update global session");
|
||||
}
|
||||
else if (LogOperation.GLOBAL_REMOVE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove global session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_ADD.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store branch session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_UPDATE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update branch session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_REMOVE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove branch session");
|
||||
}
|
||||
else {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Unknown LogOperation:" + logOperation.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transaction store manager.
|
||||
* @param transactionStoreManager the transaction store manager
|
||||
*/
|
||||
public void setTransactionStoreManager(TransactionStoreManager transactionStoreManager) {
|
||||
this.transactionStoreManager = transactionStoreManager;
|
||||
}
|
||||
|
||||
}
|
||||
-453
@@ -1,453 +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;
|
||||
|
||||
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.core.model.LockStatus;
|
||||
import io.seata.server.lock.LockerManagerFactory;
|
||||
import io.seata.server.storage.file.lock.FileLocker;
|
||||
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.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static io.seata.core.model.LockStatus.Locked;
|
||||
|
||||
/**
|
||||
* The type Branch session.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class BranchSession implements Lockable, Comparable<BranchSession>, SessionStorable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BranchSession.class);
|
||||
|
||||
private static final int MAX_BRANCH_SESSION_SIZE = StoreConfig.getMaxBranchSessionSize();
|
||||
|
||||
private static ThreadLocal<ByteBuffer> byteBufferThreadLocal = ThreadLocal
|
||||
.withInitial(() -> ByteBuffer.allocate(MAX_BRANCH_SESSION_SIZE));
|
||||
|
||||
private String xid;
|
||||
|
||||
private long transactionId;
|
||||
|
||||
private long branchId;
|
||||
|
||||
private String resourceGroupId;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private String lockKey;
|
||||
|
||||
private BranchType branchType;
|
||||
|
||||
private BranchStatus status = BranchStatus.Unknown;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private LockStatus lockStatus = Locked;
|
||||
|
||||
private ConcurrentMap<FileLocker.BucketLockMap, Set<String>> lockHolder = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 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 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 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 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 BranchType getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets branch type.
|
||||
* @param branchType the branch type
|
||||
*/
|
||||
public void setBranchType(BranchType branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status.
|
||||
* @return the status
|
||||
*/
|
||||
public BranchStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets status.
|
||||
* @param status the status
|
||||
*/
|
||||
public void setStatus(BranchStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BranchSession o) {
|
||||
return Long.compare(this.branchId, o.branchId);
|
||||
}
|
||||
|
||||
public boolean canBeCommittedAsync() {
|
||||
return branchType == BranchType.AT || status == BranchStatus.PhaseOne_Failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock holder.
|
||||
* @return the lock holder
|
||||
*/
|
||||
public ConcurrentMap<FileLocker.BucketLockMap, Set<String>> getLockHolder() {
|
||||
return lockHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() throws TransactionException {
|
||||
return this.lock(true, false);
|
||||
}
|
||||
|
||||
public boolean lock(boolean autoCommit, boolean skipCheckLock) throws TransactionException {
|
||||
if (this.getBranchType().equals(BranchType.AT)) {
|
||||
return LockerManagerFactory.getLockManager().acquireLock(this, autoCommit, skipCheckLock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() throws TransactionException {
|
||||
if (this.getBranchType() == BranchType.AT) {
|
||||
return LockerManagerFactory.getLockManager().releaseLock(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public LockStatus getLockStatus() {
|
||||
return lockStatus;
|
||||
}
|
||||
|
||||
public void setLockStatus(LockStatus lockStatus) {
|
||||
this.lockStatus = lockStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
|
||||
byte[] resourceIdBytes = resourceId != null ? resourceId.getBytes() : null;
|
||||
|
||||
byte[] lockKeyBytes = lockKey != null ? lockKey.getBytes() : null;
|
||||
|
||||
byte[] clientIdBytes = clientId != null ? clientId.getBytes() : null;
|
||||
|
||||
byte[] applicationDataBytes = applicationData != null ? applicationData.getBytes() : null;
|
||||
|
||||
byte[] xidBytes = xid != null ? xid.getBytes() : null;
|
||||
|
||||
byte branchTypeByte = branchType != null ? (byte) branchType.ordinal() : -1;
|
||||
|
||||
int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes, xidBytes);
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
if (lockKeyBytes == null) {
|
||||
throw new RuntimeException("branch session size exceeded, size : " + size + " maxBranchSessionSize : "
|
||||
+ MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
// try compress lockkey
|
||||
try {
|
||||
size -= lockKeyBytes.length;
|
||||
lockKeyBytes = CompressUtil.compress(lockKeyBytes);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.error("compress lockKey error", e);
|
||||
}
|
||||
finally {
|
||||
size += lockKeyBytes.length;
|
||||
}
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
throw new RuntimeException("compress branch session size exceeded, compressSize : " + size
|
||||
+ " maxBranchSessionSize : " + MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer byteBuffer = byteBufferThreadLocal.get();
|
||||
// recycle
|
||||
byteBuffer.clear();
|
||||
|
||||
byteBuffer.putLong(transactionId);
|
||||
byteBuffer.putLong(branchId);
|
||||
|
||||
if (resourceIdBytes != null) {
|
||||
byteBuffer.putInt(resourceIdBytes.length);
|
||||
byteBuffer.put(resourceIdBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (lockKeyBytes != null) {
|
||||
byteBuffer.putInt(lockKeyBytes.length);
|
||||
byteBuffer.put(lockKeyBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (clientIdBytes != null) {
|
||||
byteBuffer.putShort((short) clientIdBytes.length);
|
||||
byteBuffer.put(clientIdBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putShort((short) 0);
|
||||
}
|
||||
|
||||
if (applicationDataBytes != null) {
|
||||
byteBuffer.putInt(applicationDataBytes.length);
|
||||
byteBuffer.put(applicationDataBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (xidBytes != null) {
|
||||
byteBuffer.putInt(xidBytes.length);
|
||||
byteBuffer.put(xidBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
byteBuffer.put(branchTypeByte);
|
||||
|
||||
byteBuffer.put((byte) status.getCode());
|
||||
byteBuffer.put((byte) lockStatus.getCode());
|
||||
byteBuffer.flip();
|
||||
byte[] result = new byte[byteBuffer.limit()];
|
||||
byteBuffer.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int calBranchSessionSize(byte[] resourceIdBytes, byte[] lockKeyBytes, byte[] clientIdBytes,
|
||||
byte[] applicationDataBytes, byte[] xidBytes) {
|
||||
final int size = 8 // trascationId
|
||||
+ 8 // branchId
|
||||
+ 4 // resourceIdBytes.length
|
||||
+ 4 // lockKeyBytes.length
|
||||
+ 2 // clientIdBytes.length
|
||||
+ 4 // applicationDataBytes.length
|
||||
+ 4 // xidBytes.size
|
||||
+ 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) + 1; // branchType
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] a) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(a);
|
||||
this.transactionId = byteBuffer.getLong();
|
||||
this.branchId = byteBuffer.getLong();
|
||||
int resourceLen = byteBuffer.getInt();
|
||||
if (resourceLen > 0) {
|
||||
byte[] byResource = new byte[resourceLen];
|
||||
byteBuffer.get(byResource);
|
||||
this.resourceId = new String(byResource);
|
||||
}
|
||||
int lockKeyLen = byteBuffer.getInt();
|
||||
if (lockKeyLen > 0) {
|
||||
byte[] byLockKey = new byte[lockKeyLen];
|
||||
byteBuffer.get(byLockKey);
|
||||
if (CompressUtil.isCompressData(byLockKey)) {
|
||||
try {
|
||||
this.lockKey = new String(CompressUtil.uncompress(byLockKey));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("decompress lockKey error", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.lockKey = new String(byLockKey);
|
||||
}
|
||||
|
||||
}
|
||||
short clientIdLen = byteBuffer.getShort();
|
||||
if (clientIdLen > 0) {
|
||||
byte[] byClientId = new byte[clientIdLen];
|
||||
byteBuffer.get(byClientId);
|
||||
this.clientId = new String(byClientId);
|
||||
}
|
||||
int applicationDataLen = byteBuffer.getInt();
|
||||
if (applicationDataLen > 0) {
|
||||
byte[] byApplicationData = new byte[applicationDataLen];
|
||||
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);
|
||||
}
|
||||
int branchTypeId = byteBuffer.get();
|
||||
if (branchTypeId >= 0) {
|
||||
this.branchType = BranchType.values()[branchTypeId];
|
||||
}
|
||||
this.status = BranchStatus.get(byteBuffer.get());
|
||||
}
|
||||
|
||||
}
|
||||
-39
@@ -1,39 +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;
|
||||
|
||||
import io.seata.core.exception.TransactionException;
|
||||
|
||||
/**
|
||||
* The Functional Interface Branch session handler
|
||||
*
|
||||
* @author wang.liang
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BranchSessionHandler {
|
||||
|
||||
Boolean CONTINUE = null;
|
||||
|
||||
/**
|
||||
* Handle branch session.
|
||||
* @param branchSession the branch session
|
||||
* @return the handle result
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
Boolean handle(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
}
|
||||
-754
@@ -1,754 +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;
|
||||
|
||||
import io.seata.common.Constants;
|
||||
import io.seata.common.DefaultValues;
|
||||
import io.seata.common.XID;
|
||||
import io.seata.common.util.StringUtils;
|
||||
import io.seata.config.ConfigurationFactory;
|
||||
import io.seata.core.constants.ConfigurationKeys;
|
||||
import io.seata.core.exception.GlobalTransactionException;
|
||||
import io.seata.core.exception.TransactionException;
|
||||
import io.seata.core.exception.TransactionExceptionCode;
|
||||
import io.seata.core.model.BranchStatus;
|
||||
import io.seata.core.model.BranchType;
|
||||
import io.seata.core.model.GlobalStatus;
|
||||
import io.seata.core.model.LockStatus;
|
||||
import io.seata.server.UUIDGenerator;
|
||||
import io.seata.server.lock.LockerManagerFactory;
|
||||
import io.seata.server.store.SessionStorable;
|
||||
import io.seata.server.store.StoreConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static io.seata.core.model.GlobalStatus.*;
|
||||
|
||||
/**
|
||||
* The type Global session.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public class GlobalSession implements SessionLifecycle, SessionStorable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalSession.class);
|
||||
|
||||
private static final int MAX_GLOBAL_SESSION_SIZE = StoreConfig.getMaxGlobalSessionSize();
|
||||
|
||||
private static ThreadLocal<ByteBuffer> byteBufferThreadLocal = ThreadLocal
|
||||
.withInitial(() -> ByteBuffer.allocate(MAX_GLOBAL_SESSION_SIZE));
|
||||
|
||||
/**
|
||||
* If the global session's status is (Rollbacking or Committing) and currentTime -
|
||||
* createTime >= RETRY_DEAD_THRESHOLD then the tx will be remand as need to retry
|
||||
* rollback
|
||||
*/
|
||||
private static final int RETRY_DEAD_THRESHOLD = ConfigurationFactory.getInstance()
|
||||
.getInt(ConfigurationKeys.RETRY_DEAD_THRESHOLD, DefaultValues.DEFAULT_RETRY_DEAD_THRESHOLD);
|
||||
|
||||
private String xid;
|
||||
|
||||
private long transactionId;
|
||||
|
||||
private volatile GlobalStatus status;
|
||||
|
||||
private String applicationId;
|
||||
|
||||
private String transactionServiceGroup;
|
||||
|
||||
private String transactionName;
|
||||
|
||||
private int timeout;
|
||||
|
||||
private long beginTime;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private final boolean lazyLoadBranch;
|
||||
|
||||
private volatile boolean active = true;
|
||||
|
||||
private List<BranchSession> branchSessions;
|
||||
|
||||
private GlobalSessionLock globalSessionLock = new GlobalSessionLock();
|
||||
|
||||
/**
|
||||
* Add boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean add(BranchSession branchSession) {
|
||||
if (null != branchSessions) {
|
||||
return branchSessions.add(branchSession);
|
||||
}
|
||||
else {
|
||||
// db and redis no need to deal with
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean remove(BranchSession branchSession) {
|
||||
return branchSessions.remove(branchSession);
|
||||
}
|
||||
|
||||
private Set<SessionLifecycleListener> lifecycleListeners = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Can be committed async boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean canBeCommittedAsync() {
|
||||
List<BranchSession> branchSessions = getBranchSessions();
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
if (!branchSession.canBeCommittedAsync()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has AT branch
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean hasATBranch() {
|
||||
List<BranchSession> branchSessions = getBranchSessions();
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
if (branchSession.getBranchType() == BranchType.AT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is saga type transaction
|
||||
* @return is saga
|
||||
*/
|
||||
public boolean isSaga() {
|
||||
List<BranchSession> branchSessions = getBranchSessions();
|
||||
if (branchSessions.size() > 0) {
|
||||
return BranchType.SAGA == branchSessions.get(0).getBranchType();
|
||||
}
|
||||
else {
|
||||
return StringUtils.isNotBlank(transactionName)
|
||||
&& transactionName.startsWith(Constants.SAGA_TRANS_NAME_PREFIX);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is timeout boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isTimeout() {
|
||||
return (System.currentTimeMillis() - beginTime) > timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* prevent could not handle committing and rollbacking transaction
|
||||
* @return if true retry commit or roll back
|
||||
*/
|
||||
public boolean isDeadSession() {
|
||||
return (System.currentTimeMillis() - beginTime) > RETRY_DEAD_THRESHOLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void begin() throws TransactionException {
|
||||
this.status = GlobalStatus.Begin;
|
||||
this.beginTime = System.currentTimeMillis();
|
||||
this.active = true;
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onBegin(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeGlobalStatus(GlobalStatus status) throws TransactionException {
|
||||
if (GlobalStatus.Rollbacking == status) {
|
||||
LockerManagerFactory.getLockManager().updateLockStatus(xid, LockStatus.Rollbacking);
|
||||
}
|
||||
this.status = status;
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onStatusChange(this, status);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeBranchStatus(BranchSession branchSession, BranchStatus status) throws TransactionException {
|
||||
branchSession.setStatus(status);
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onBranchStatusChange(this, branchSession, status);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws TransactionException {
|
||||
if (active) {
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onClose(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() throws TransactionException {
|
||||
if (isSuccessEnd()) {
|
||||
// Clean locks first
|
||||
clean();
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onSuccessEnd(this);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onFailEnd(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSuccessEnd() {
|
||||
if (status == GlobalStatus.Committed || status == GlobalStatus.Rollbacked
|
||||
|| status == GlobalStatus.TimeoutRollbacked) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void clean() throws TransactionException {
|
||||
if (!LockerManagerFactory.getLockManager().releaseGlobalSessionLock(this)) {
|
||||
throw new TransactionException("UnLock globalSession error, xid = " + this.xid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close and clean.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public void closeAndClean() throws TransactionException {
|
||||
close();
|
||||
if (this.hasATBranch()) {
|
||||
clean();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add session lifecycle listener.
|
||||
* @param sessionLifecycleListener the session lifecycle listener
|
||||
*/
|
||||
public void addSessionLifecycleListener(SessionLifecycleListener sessionLifecycleListener) {
|
||||
lifecycleListeners.add(sessionLifecycleListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove session lifecycle listener.
|
||||
* @param sessionLifecycleListener the session lifecycle listener
|
||||
*/
|
||||
public void removeSessionLifecycleListener(SessionLifecycleListener sessionLifecycleListener) {
|
||||
lifecycleListeners.remove(sessionLifecycleListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranch(BranchSession branchSession) throws TransactionException {
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onAddBranch(this, branchSession);
|
||||
}
|
||||
branchSession.setStatus(BranchStatus.Registered);
|
||||
add(branchSession);
|
||||
}
|
||||
|
||||
public void loadBranchs() {
|
||||
if (branchSessions == null && isLazyLoadBranch()) {
|
||||
synchronized (this) {
|
||||
if (branchSessions == null && isLazyLoadBranch()) {
|
||||
branchSessions = new ArrayList<>();
|
||||
Optional.ofNullable(SessionHolder.getRootSessionManager().findGlobalSession(xid, true))
|
||||
.ifPresent(globalSession -> branchSessions.addAll(globalSession.getBranchSessions()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBranch(BranchSession branchSession) throws TransactionException {
|
||||
// do not unlock if global status in (Committing, CommitRetrying,
|
||||
// AsyncCommitting),
|
||||
// because it's already unlocked in 'DefaultCore.commit()'
|
||||
if (status != Committing && status != CommitRetrying && status != AsyncCommitting) {
|
||||
if (!branchSession.unlock()) {
|
||||
throw new TransactionException(
|
||||
"Unlock branch lock failed, xid = " + this.xid + ", branchId = " + branchSession.getBranchId());
|
||||
}
|
||||
}
|
||||
for (SessionLifecycleListener lifecycleListener : lifecycleListeners) {
|
||||
lifecycleListener.onRemoveBranch(this, branchSession);
|
||||
}
|
||||
remove(branchSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets branch.
|
||||
* @param branchId the branch id
|
||||
* @return the branch
|
||||
*/
|
||||
public BranchSession getBranch(long branchId) {
|
||||
synchronized (this) {
|
||||
List<BranchSession> branchSessions = getBranchSessions();
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
if (branchSession.getBranchId() == branchId) {
|
||||
return branchSession;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets sorted branches.
|
||||
* @return the sorted branches
|
||||
*/
|
||||
public List<BranchSession> getSortedBranches() {
|
||||
return new ArrayList<>(getBranchSessions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reverse sorted branches.
|
||||
* @return the reverse sorted branches
|
||||
*/
|
||||
public List<BranchSession> getReverseSortedBranches() {
|
||||
List<BranchSession> reversed = new ArrayList<>(getBranchSessions());
|
||||
Collections.reverse(reversed);
|
||||
return reversed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Global session.
|
||||
*/
|
||||
public GlobalSession() {
|
||||
this.lazyLoadBranch = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Global session.
|
||||
* @param applicationId the application id
|
||||
* @param transactionServiceGroup the transaction service group
|
||||
* @param transactionName the transaction name
|
||||
* @param timeout the timeout
|
||||
* @param lazyLoadBranch the lazy load branch
|
||||
*/
|
||||
public GlobalSession(String applicationId, String transactionServiceGroup, String transactionName, int timeout,
|
||||
boolean lazyLoadBranch) {
|
||||
this.transactionId = UUIDGenerator.generateUUID();
|
||||
this.status = GlobalStatus.Begin;
|
||||
this.lazyLoadBranch = lazyLoadBranch;
|
||||
if (!lazyLoadBranch) {
|
||||
this.branchSessions = new ArrayList<>();
|
||||
}
|
||||
this.applicationId = applicationId;
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
this.transactionName = transactionName;
|
||||
this.timeout = timeout;
|
||||
this.xid = XID.generateXID(transactionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Global session.
|
||||
* @param applicationId the application id
|
||||
* @param transactionServiceGroup the transaction service group
|
||||
* @param transactionName the transaction name
|
||||
* @param timeout the timeout
|
||||
*/
|
||||
public GlobalSession(String applicationId, String transactionServiceGroup, String transactionName, int timeout) {
|
||||
this(applicationId, transactionServiceGroup, transactionName, timeout, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 status.
|
||||
* @return the status
|
||||
*/
|
||||
public GlobalStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets status.
|
||||
* @param status the status
|
||||
*/
|
||||
public 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.
|
||||
* @return the application id
|
||||
*/
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets transaction service group.
|
||||
* @return the transaction service group
|
||||
*/
|
||||
public String getTransactionServiceGroup() {
|
||||
return transactionServiceGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets transaction name.
|
||||
* @return the transaction name
|
||||
*/
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets timeout.
|
||||
* @return the timeout
|
||||
*/
|
||||
public int getTimeout() {
|
||||
return 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 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;
|
||||
}
|
||||
|
||||
public boolean isLazyLoadBranch() {
|
||||
return lazyLoadBranch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create global session global session.
|
||||
* @param applicationId the application id
|
||||
* @param txServiceGroup the tx service group
|
||||
* @param txName the tx name
|
||||
* @param timeout the timeout
|
||||
* @return the global session
|
||||
*/
|
||||
public static GlobalSession createGlobalSession(String applicationId, String txServiceGroup, String txName,
|
||||
int timeout) {
|
||||
GlobalSession session = new GlobalSession(applicationId, txServiceGroup, txName, timeout, false);
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets active.
|
||||
* @param active the active
|
||||
*/
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
byte[] byApplicationIdBytes = applicationId != null ? applicationId.getBytes() : null;
|
||||
|
||||
byte[] byServiceGroupBytes = transactionServiceGroup != null ? transactionServiceGroup.getBytes() : null;
|
||||
|
||||
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);
|
||||
|
||||
if (size > MAX_GLOBAL_SESSION_SIZE) {
|
||||
throw new RuntimeException("global session size exceeded, size : " + size + " maxBranchSessionSize : "
|
||||
+ MAX_GLOBAL_SESSION_SIZE);
|
||||
}
|
||||
ByteBuffer byteBuffer = byteBufferThreadLocal.get();
|
||||
// recycle
|
||||
byteBuffer.clear();
|
||||
|
||||
byteBuffer.putLong(transactionId);
|
||||
byteBuffer.putInt(timeout);
|
||||
if (byApplicationIdBytes != null) {
|
||||
byteBuffer.putShort((short) byApplicationIdBytes.length);
|
||||
byteBuffer.put(byApplicationIdBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putShort((short) 0);
|
||||
}
|
||||
if (byServiceGroupBytes != null) {
|
||||
byteBuffer.putShort((short) byServiceGroupBytes.length);
|
||||
byteBuffer.put(byServiceGroupBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putShort((short) 0);
|
||||
}
|
||||
if (byTxNameBytes != null) {
|
||||
byteBuffer.putShort((short) byTxNameBytes.length);
|
||||
byteBuffer.put(byTxNameBytes);
|
||||
}
|
||||
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();
|
||||
byte[] result = new byte[byteBuffer.limit()];
|
||||
byteBuffer.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int calGlobalSessionSize(byte[] byApplicationIdBytes, byte[] byServiceGroupBytes, byte[] byTxNameBytes,
|
||||
byte[] xidBytes, byte[] applicationDataBytes) {
|
||||
final int size = 8 // transactionId
|
||||
+ 4 // timeout
|
||||
+ 2 // byApplicationIdBytes.length
|
||||
+ 2 // byServiceGroupBytes.length
|
||||
+ 2 // byTxNameBytes.length
|
||||
+ 4 // xidBytes.length
|
||||
+ 4 // applicationDataBytes.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);
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] a) {
|
||||
this.branchSessions = new ArrayList<>();
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(a);
|
||||
this.transactionId = byteBuffer.getLong();
|
||||
this.timeout = byteBuffer.getInt();
|
||||
short applicationIdLen = byteBuffer.getShort();
|
||||
if (applicationIdLen > 0) {
|
||||
byte[] byApplicationId = new byte[applicationIdLen];
|
||||
byteBuffer.get(byApplicationId);
|
||||
this.applicationId = new String(byApplicationId);
|
||||
}
|
||||
short serviceGroupLen = byteBuffer.getShort();
|
||||
if (serviceGroupLen > 0) {
|
||||
byte[] byServiceGroup = new byte[serviceGroupLen];
|
||||
byteBuffer.get(byServiceGroup);
|
||||
this.transactionServiceGroup = new String(byServiceGroup);
|
||||
}
|
||||
short txNameLen = byteBuffer.getShort();
|
||||
if (txNameLen > 0) {
|
||||
byte[] byTxName = new byte[txNameLen];
|
||||
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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Has branch boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean hasBranch() {
|
||||
return getBranchSessions().size() > 0;
|
||||
}
|
||||
|
||||
public void lock() throws TransactionException {
|
||||
globalSessionLock.lock();
|
||||
}
|
||||
|
||||
public void unlock() {
|
||||
globalSessionLock.unlock();
|
||||
}
|
||||
|
||||
private static class GlobalSessionLock {
|
||||
|
||||
private Lock globalSessionLock = new ReentrantLock();
|
||||
|
||||
private static final int GLOBAL_SESSION_LOCK_TIME_OUT_MILLS = 2 * 1000;
|
||||
|
||||
public void lock() throws TransactionException {
|
||||
try {
|
||||
if (globalSessionLock.tryLock(GLOBAL_SESSION_LOCK_TIME_OUT_MILLS, TimeUnit.MILLISECONDS)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
LOGGER.error("Interrupted error", e);
|
||||
}
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedLockGlobalTranscation,
|
||||
"Lock global session failed");
|
||||
}
|
||||
|
||||
public void unlock() {
|
||||
globalSessionLock.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface LockRunnable {
|
||||
|
||||
void run() throws TransactionException;
|
||||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface LockCallable<V> {
|
||||
|
||||
V call() throws TransactionException;
|
||||
|
||||
}
|
||||
|
||||
public List<BranchSession> getBranchSessions() {
|
||||
loadBranchs();
|
||||
return branchSessions;
|
||||
}
|
||||
|
||||
public void asyncCommit() throws TransactionException {
|
||||
this.addSessionLifecycleListener(SessionHolder.getAsyncCommittingSessionManager());
|
||||
this.setStatus(GlobalStatus.AsyncCommitting);
|
||||
SessionHolder.getAsyncCommittingSessionManager().addGlobalSession(this);
|
||||
}
|
||||
|
||||
public void queueToRetryCommit() throws TransactionException {
|
||||
this.addSessionLifecycleListener(SessionHolder.getRetryCommittingSessionManager());
|
||||
this.setStatus(GlobalStatus.CommitRetrying);
|
||||
SessionHolder.getRetryCommittingSessionManager().addGlobalSession(this);
|
||||
}
|
||||
|
||||
public void queueToRetryRollback() throws TransactionException {
|
||||
this.addSessionLifecycleListener(SessionHolder.getRetryRollbackingSessionManager());
|
||||
GlobalStatus currentStatus = this.getStatus();
|
||||
if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) {
|
||||
this.setStatus(GlobalStatus.TimeoutRollbackRetrying);
|
||||
}
|
||||
else {
|
||||
this.setStatus(GlobalStatus.RollbackRetrying);
|
||||
}
|
||||
SessionHolder.getRetryRollbackingSessionManager().addGlobalSession(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSession{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", status=" + status
|
||||
+ ", applicationId='" + applicationId + '\'' + ", transactionServiceGroup='" + transactionServiceGroup
|
||||
+ '\'' + ", transactionName='" + transactionName + '\'' + ", timeout=" + timeout + ", beginTime="
|
||||
+ beginTime + ", applicationData='" + applicationData + '\'' + ", lazyLoadBranch=" + lazyLoadBranch
|
||||
+ ", active=" + active + ", branchSessions=" + branchSessions + ", globalSessionLock="
|
||||
+ globalSessionLock + ", lifecycleListeners=" + lifecycleListeners + '}';
|
||||
}
|
||||
|
||||
}
|
||||
-36
@@ -1,36 +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;
|
||||
|
||||
import io.seata.core.exception.TransactionException;
|
||||
|
||||
/**
|
||||
* The Functional Interface Global session handler
|
||||
*
|
||||
* @author wang.liang
|
||||
* @since 1.5.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface GlobalSessionHandler {
|
||||
|
||||
/**
|
||||
* Handle global session.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void handle(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
}
|
||||
@@ -1,41 +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;
|
||||
|
||||
import io.seata.core.exception.TransactionException;
|
||||
|
||||
/**
|
||||
* The interface Lockable.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public interface Lockable {
|
||||
|
||||
/**
|
||||
* Lock boolean.
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean lock() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Unlock boolean.
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean unlock() throws TransactionException;
|
||||
|
||||
}
|
||||
@@ -1,30 +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;
|
||||
|
||||
/**
|
||||
* Service contains states which can be reloaded.
|
||||
*
|
||||
* @author sharajava
|
||||
*/
|
||||
public interface Reloadable {
|
||||
|
||||
/**
|
||||
* Reload states.
|
||||
*/
|
||||
void reload();
|
||||
|
||||
}
|
||||
Loaded 100 of 545 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user