Skip to content

Commit

Permalink
feature: TCC mode support idempotent and anti hanging (apache#3545)
Browse files Browse the repository at this point in the history
  • Loading branch information
kaka2code committed May 23, 2021
1 parent 49b4665 commit 9dfb624
Show file tree
Hide file tree
Showing 26 changed files with 1,247 additions and 23 deletions.
4 changes: 3 additions & 1 deletion changes/1.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [[#3642](https://github.com/seata/seata/pull/3642)] TCC模式支持使用API的形式进行二阶段参数传递
- [[#3064](https://github.com/seata/seata/pull/3064)] 支持可配置GlobalTransactionInterceptor和TccActionInterceptor的order值。
- [[#3374](https://github.com/seata/seata/pull/2852)] 支持自定义`GlobalTransactionScanner`的扫描对象。
- [[#3545](https://github.com/seata/seata/pull/3545)] TCC模式支持幂等控制、防悬挂和空回滚
- [[#3009](https://github.com/seata/seata/pull/3009)] 支持server端以springboot的方式的启动
- [[#3652](https://github.com/seata/seata/pull/3652)] 支持APM SkyWalking监控。

Expand Down Expand Up @@ -73,7 +74,8 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [xingfudeshi](https://github.com/xingfudeshi)
- [wangliang181230](https://github.com/wangliang181230)
- [spilledyear](https://github.com/spilledyear)

- [kaka2code](https://github.com/kaka2code)


同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。

Expand Down
2 changes: 2 additions & 0 deletions changes/en-us/1.5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- [[#3642](https://github.com/seata/seata/pull/3642)] provide an api to share tcc phase-1's params to phase-2
- [[#3064](https://github.com/seata/seata/pull/3064)] support configuring the order of the TM and TCC interceptor
- [[#3374](https://github.com/seata/seata/pull/2852)] support configuring scan target for GlobalTransactionScanner
- [[#3545](https://github.com/seata/seata/pull/3545)] TCC mode support idempotent and anti hanging
- [[#3009](https://github.com/seata/seata/pull/3009)] support server start with springboot and config with application.yaml
- [[#3652](https://github.com/seata/seata/pull/3652)] support APM with SkyWalking

Expand Down Expand Up @@ -74,6 +75,7 @@
- [xingfudeshi](https://github.com/xingfudeshi)
- [wangliang181230](https://github.com/wangliang181230)
- [spilledyear](https://github.com/spilledyear)
- [kaka2code](https://github.com/kaka2code)


Also, we receive many valuable issues, questions and advices from our community. Thanks for you all.
Expand Down
5 changes: 5 additions & 0 deletions common/src/main/java/io/seata/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public interface Constants {
*/
String ACTION_NAME = "actionName";

/**
* Use TCC fence
*/
String USE_TCC_FENCE = "useTCCFence";

/**
* phase one method name
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,33 @@ public enum FrameworkErrorCode {
*/
StateMachineNoChoiceMatched("0422", "State machine no choice matched", "State machine no choice matched"),

/** 0500~0599 TCC fence related error **/

/**
* TCC fence datasource need injected
*/
DateSourceNeedInjected("0501","TCC fence datasource need injected","TCC fence datasource need injected"),

/**
* TCC fence record already exists
*/
RecordAlreadyExists("0502","TCC fence record already exists","TCC fence record already exists"),

/**
* Insert tcc fence record error
*/
InsertRecordError("0503","Insert tcc fence record error","Insert tcc fence record error"),

/**
* Insert tcc fence record duplicate key exception
*/
DuplicateKeyException("0504", "Insert tcc fence record duplicate key exception", "Insert tcc fence record duplicate key exception"),

/**
* TCC fence transactionManager need injected
*/
TransactionManagerNeedInjected("0505","TCC fence transactionManager need injected","TCC fence transactionManager need injected"),

/**
* Undefined error
*/
Expand Down
7 changes: 6 additions & 1 deletion script/client/spring/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,9 @@ seata.registry.zk.connect-timeout=2000
seata.registry.zk.username=
seata.registry.zk.password=

seata.registry.custom.name=
seata.registry.custom.name=

seata.tcc-fence.enable=true
seata.tcc-fence.config.log-table-name=tcc_fence_log
seata.tcc-fence.config.clean-mode=hour
seata.tcc-fence.config.clean-period=1
8 changes: 7 additions & 1 deletion script/client/spring/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,10 @@ seata:
custom:
name: ""
log:
exception-rate: 100
exception-rate: 100
tcc-fence:
enable: true
config:
log-table-name: tcc_fence_log
clean-mode: hour
clean-period: 1
13 changes: 13 additions & 0 deletions script/client/tcc/db/mysql.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- -------------------------------- The script use tcc fence --------------------------------
CREATE TABLE IF NOT EXISTS `tcc_fence_log`
(
`xid` VARCHAR(128) NOT NULL COMMENT 'global id',
`branch_id` BIGINT NOT NULL COMMENT 'branch id',
`status` TINYINT NOT NULL COMMENT 'status(tried:1;committed:2;rollbacked:3;suspended:4)',
`gmt_create` DATETIME(3) NOT NULL COMMENT 'create time',
`gmt_modified` DATETIME(3) NOT NULL COMMENT 'update time',
PRIMARY KEY (`xid`, `branch_id`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_status` (`status`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8;
11 changes: 11 additions & 0 deletions script/client/tcc/db/oracle.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CREATE TABLE tcc_fence_log
(
xid VARCHAR2(128) NOT NULL,
branch_id NUMBER(19) NOT NULL,
status NUMBER(3) NOT NULL,
gmt_create TIMESTAMP(3) NOT NULL,
gmt_modified TIMESTAMP(3) NOT NULL,
PRIMARY KEY (xid, branch_id)
);
CREATE INDEX idx_gmt_modified ON tcc_fence_log (gmt_modified);
CREATE INDEX idx_status ON tcc_fence_log (status);
12 changes: 12 additions & 0 deletions script/client/tcc/db/postgresql.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- -------------------------------- The script used for tcc fence --------------------------------
CREATE TABLE IF NOT EXISTS public.tcc_fence_log
(
xid VARCHAR(128) NOT NULL,
branch_id BIGINT NOT NULL,
status SMALLINT NOT NULL,
gmt_create TIMESTAMP(3) NOT NULL,
gmt_modified TIMESTAMP(3) NOT NULL,
CONSTRAINT pk_tcc_fence_log PRIMARY KEY (xid, branch_id)
);
CREATE INDEX idx_gmt_modified ON public.tcc_fence_log (gmt_modified);
CREATE INDEX idx_status ON public.tcc_fence_log (status);
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 1999-2019 Seata.io Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.seata.spring.boot.autoconfigure;

import io.seata.rm.tcc.config.TCCFenceConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

/**
* TCC fence auto configuration.
*
* @author kaka2code
*/
@ConditionalOnExpression("${seata.enabled:true} && ${seata.tccFence.enabled:true} && ${seata.tcc-fence.enabled:true}")
@AutoConfigureAfter({DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class})
public class SeataTCCFenceAutoConfiguration {

public static final String TCC_FENCE_DATA_SOURCE_BEAN_NAME = "seataTCCFenceDataSource";
public static final String TCC_FENCE_TRANSACTION_MANAGER_BEAN_NAME = "seataTCCFenceTransactionManager";

@Bean
@ConditionalOnMissingBean(TCCFenceConfig.class)
@ConditionalOnBean({DataSource.class, PlatformTransactionManager.class})
@ConfigurationProperties(StarterConstants.TCC_FENCE_CONFIG_PREFIX_KEBAB_STYLE)
public TCCFenceConfig tccFenceConfig(
DataSource dataSource,
PlatformTransactionManager transactionManager,
@Qualifier(TCC_FENCE_DATA_SOURCE_BEAN_NAME) @Autowired(required = false) DataSource tccFenceDataSource,
@Qualifier(TCC_FENCE_TRANSACTION_MANAGER_BEAN_NAME) @Autowired(required = false) PlatformTransactionManager tccFenceTransactionManager) {
return new TCCFenceConfig(tccFenceDataSource != null ? tccFenceDataSource : dataSource,
tccFenceTransactionManager != null ? tccFenceTransactionManager : transactionManager);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,34 @@
"replacement": "seata.client.load-balance.virtual-nodes",
"reason": "Please configure to 'seata.client.load-balance.virtual-nodes'."
}
},
{
"name": "seata.tcc-fence.enabled",
"type": "java.lang.Boolean",
"description": "Whether enable tcc fence configuration.",
"sourceType": "io.seata.spring.boot.autoconfigure.SeataTCCFenceAutoConfiguration",
"defaultValue": false
},
{
"name": "seata.tcc-fence.config.log-table-name",
"type": "java.lang.String",
"description": "TCC fence log table name.",
"sourceType": "io.seata.rm.tcc.config.TCCFenceConfig",
"defaultValue": "tcc_fence_log"
},
{
"name": "seata.tcc-fence.config.clean-mode",
"type": "java.lang.String",
"description": "TCC fence log clean mode.",
"sourceType": "io.seata.rm.tcc.config.TCCFenceConfig",
"defaultValue": "hour"
},
{
"name": "seata.tcc-fence.config.clean-period",
"type": "java.lang.Integer",
"description": "TCC fence log clean period.",
"sourceType": "io.seata.rm.tcc.config.TCCFenceConfig",
"defaultValue": 1
}
],
"hints": [
Expand Down Expand Up @@ -326,6 +354,17 @@
}
}
]
},
{
"name": "seata.tcc-fence.config.clean-mode",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "io.seata.rm.tcc.constant.TCCFenceCleanMode"
}
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.seata.spring.boot.autoconfigure.SeataClientPropertiesAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.seata.spring.boot.autoconfigure.SeataClientPropertiesAutoConfiguration,\
io.seata.spring.boot.autoconfigure.SeataTCCFenceAutoConfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public interface StarterConstants {
String LOAD_BALANCE_PREFIX = CLIENT_PREFIX + ".loadBalance";
String LOG_PREFIX = SEATA_PREFIX + ".log";
String COMPRESS_PREFIX = UNDO_PREFIX + ".compress";
String TCC_FENCE_PREFIX_KEBAB_STYLE = SEATA_PREFIX + ".tcc-fence";
String TCC_FENCE_CONFIG_PREFIX_KEBAB_STYLE = TCC_FENCE_PREFIX_KEBAB_STYLE + ".config";

String REGISTRY_PREFIX = SEATA_PREFIX + ".registry";
String REGISTRY_NACOS_PREFIX = REGISTRY_PREFIX + ".nacos";
Expand Down
4 changes: 4 additions & 0 deletions tcc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
<artifactId>seata-rm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
Expand Down
Loading

0 comments on commit 9dfb624

Please sign in to comment.