Skip to content

Commit 83caaa7

Browse files
committed
Bump the minimum Seata Client version for Seata AT integration to 2.2.0
1 parent 60fae79 commit 83caaa7

File tree

26 files changed

+537
-252
lines changed

26 files changed

+537
-252
lines changed

RELEASE-NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
1. Proxy Native: Support local transactions of ClickHouse under GraalVM Native Image - [#33801](https://github.com/apache/shardingsphere/pull/33801)
3232
1. Doc: Adds documentation for ClickHouse support - [#33779](https://github.com/apache/shardingsphere/pull/33779)
3333
1. Doc: Removes use of `iceberg.mr.schema.auto.conversion` from documentation due to HIVE-26507 - [#33828](https://github.com/apache/shardingsphere/pull/33828)
34+
1. Kernel: Bump the minimum Seata Client version for Seata AT integration to 2.2.0 - [#33872](https://github.com/apache/shardingsphere/pull/33872)
3435

3536
### Bug Fixes
3637

docs/document/content/user-manual/shardingsphere-jdbc/special-api/transaction/seata.cn.md

Lines changed: 214 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Apache ShardingSphere 提供 BASE 事务,集成了 Seata 的实现。本文所
99

1010
## 前提条件
1111

12-
ShardingSphere 的 Seata 集成仅在 `apache/incubator-seata:v2.1.0` 或更高版本可用。
12+
ShardingSphere 的 Seata 集成仅在 `apache/incubator-seata:v2.2.0` 或更高版本可用。
1313
对于 `org.apache.seata:seata-all` Maven 模块对应的 Seata Client,此限制同时作用于 HotSpot VM 和 GraalVM Native Image。
1414
引入 Maven 依赖,并排除 `org.apache.seata:seata-all` 中过时的 `org.antlr:antlr4-runtime:4.8` 的 Maven 依赖。
1515

@@ -29,7 +29,7 @@ ShardingSphere 的 Seata 集成仅在 `apache/incubator-seata:v2.1.0` 或更高
2929
<dependency>
3030
<groupId>org.apache.seata</groupId>
3131
<artifactId>seata-all</artifactId>
32-
<version>2.1.0</version>
32+
<version>2.2.0</version>
3333
<exclusions>
3434
<exclusion>
3535
<groupId>org.antlr</groupId>
@@ -42,47 +42,17 @@ ShardingSphere 的 Seata 集成仅在 `apache/incubator-seata:v2.1.0` 或更高
4242
```
4343

4444
受 Calcite 的影响,ShardingSphere JDBC 使用的 `commons-lang:commons-lang``org.apache.commons:commons-pool2` 与 Seata Client 存在依赖冲突,
45-
需用户根据实际情景考虑是否需要解决依赖冲突。
45+
需用户根据实际情景考虑是否需要解决依赖冲突。如果不解决依赖冲突,Maven 等构建工具会在 classpath 随机使用一个冲突依赖的版本。
4646

4747
使用 ShardingSphere 的 Seata 集成模块时,ShardingSphere 连接的数据库实例应同时实现 ShardingSphere 的方言解析支持与 Seata AT 模式的方言解析支持。
4848
这类数据库包括但不限于 `mysql``gvenzl/oracle-free``gvenzl/oracle-xe``postgres``mcr.microsoft.com/mssql/server` 等 Docker Image。
4949

50-
## 操作步骤
51-
52-
1. 启动 Seata Server
53-
2. 创建日志表
54-
3. 添加 Seata 配置
55-
56-
## 配置示例
57-
58-
### 启动 Seata Server
59-
60-
按照如下任一链接的步骤,下载并启动 Seata 服务器。
61-
合理的启动方式应通过 Docker Hub 中的 `apache/seata-server` 的 Docker Image 来实例化 Seata 服务器。
50+
### `undo_log` 表限制
6251

63-
- https://hub.docker.com/r/apache/seata-server
52+
在每一个 ShardingSphere 涉及的真实数据库实例中均需要创建 `undo_log` 表。
53+
每种数据库的 SQL 的内容以 https://github.com/apache/incubator-seata/tree/v2.2.0/script/client/at/db 内对应的数据库为准。
6454

65-
### 创建 undo_log 表
66-
67-
在每一个 ShardingSphere 涉及的真实数据库实例中创建 `undo_log` 表。
68-
SQL 的内容以 https://github.com/apache/incubator-seata/tree/v2.1.0/script/client/at/db 内对应的数据库为准。
69-
以下内容以 MySQL 为例。
70-
```sql
71-
CREATE TABLE IF NOT EXISTS `undo_log`
72-
(
73-
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
74-
`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
75-
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
76-
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
77-
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
78-
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
79-
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
80-
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
81-
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
82-
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
83-
```
84-
85-
### 修改配置
55+
### 相关配置
8656

8757
在自有项目的 ShardingSphere 的 YAML 配置文件写入如下内容,参考 [分布式事务](/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/transaction)
8858
若初始化 ShardingSphere JDBC DataSource 时使用的是 Java API,参考 [分布式事务](/cn/user-manual/shardingsphere-jdbc/java-api/rules/transaction)
@@ -93,16 +63,16 @@ transaction:
9363
providerType: Seata
9464
```
9565
96-
在 classpath 的根目录中增加 `seata.conf` 文件,
97-
配置文件格式参考 `org.apache.seata.config.FileConfiguration` 的 [JavaDoc](https://github.com/apache/incubator-seata/blob/v2.1.0/config/seata-config-core/src/main/java/org/apache/seata/config/FileConfiguration.java)。
66+
在 classpath 的根目录中增加 `seata.conf` 文件,
67+
配置文件格式参考 `org.apache.seata.config.FileConfiguration` 的 [JavaDoc](https://github.com/apache/incubator-seata/blob/v2.2.0/config/seata-config-core/src/main/java/org/apache/seata/config/FileConfiguration.java)。
9868

9969
`seata.conf` 存在四个属性,
10070

10171
1. `shardingsphere.transaction.seata.at.enable`,当此值为`true`时,开启 ShardingSphere 的 Seata AT 集成。存在默认值为 `true`
10272
2. `shardingsphere.transaction.seata.tx.timeout`,全局事务超时(秒)。存在默认值为 `60`
10373
3. `client.application.id`,应用唯一主键,用于设置 Seata Transaction Manager Client 和 Seata Resource Manager Client 的 `applicationId`
10474
4. `client.transaction.service.group`,所属事务组, 用于设置 Seata Transaction Manager Client 和 Seata Resource Manager Client 的 `transactionServiceGroup`。
105-
存在默认值为 `default`
75+
存在默认值为 `default`
10676

10777
一个完全配置的 `seata.conf` 如下,
10878

@@ -117,7 +87,7 @@ client {
11787
```
11888

11989
一个最小配置的 `seata.conf` 如下。
120-
由 ShardingSphere 管理的 `seata.conf` 中, `client.transaction.service.group` 的默认值设置为 `default` 是出于历史原因。
90+
由 ShardingSphere 管理的 `seata.conf` 中, `client.transaction.service.group` 的默认值为 `default` 是出于历史原因。
12191
假设用户使用的 Seata Server 和 Seata Client 的 `registry.conf` 中,`registry.type` 和 `config.type` 均为 `file`,
12292
则对于 `registry.conf` 的 `config.file.name` 配置的 `.conf` 文件中,事务分组名在 `apache/incubator-seata:v1.5.1` 及之后默认值为 `default_tx_group`,
12393
在 `apache/incubator-seata:v1.5.1` 之前则为 `my_test_tx_group`。
@@ -128,6 +98,200 @@ client.application.id = example
12898

12999
根据实际场景修改 Seata 的 `registry.conf` 文件。
130100

101+
## 操作步骤
102+
103+
1. 启动 Seata Server
104+
2. 创建 `undo_log` 表
105+
3. 添加 Seata 配置
106+
107+
## 配置示例
108+
109+
### 启动 Seata Server 和 MySQL Server
110+
111+
编写 Docker Compose 文件来启动 Seata Server 和 MySQL Server。
112+
113+
```yaml
114+
services:
115+
apache-seata-server:
116+
image: apache/seata-server:2.2.0
117+
ports:
118+
- "8091:8091"
119+
mysql:
120+
image: mysql:9.1.0
121+
environment:
122+
MYSQL_ROOT_PASSWORD: example
123+
volumes:
124+
- ./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
125+
ports:
126+
- "3306:3306"
127+
```
128+
129+
`./docker-entrypoint-initdb.d` 文件夹包含文件为 `init.sh`,内容如下,
130+
131+
```shell
132+
#!/bin/bash
133+
set -e
134+
135+
mysql -uroot -p"$MYSQL_ROOT_PASSWORD" <<EOSQL
136+
CREATE DATABASE demo_ds_0;
137+
CREATE DATABASE demo_ds_1;
138+
CREATE DATABASE demo_ds_2;
139+
EOSQL
140+
141+
for i in "demo_ds_0" "demo_ds_1" "demo_ds_2"
142+
do
143+
mysql -uroot -p"$MYSQL_ROOT_PASSWORD" "$i" <<'EOSQL'
144+
CREATE TABLE IF NOT EXISTS `undo_log`
145+
(
146+
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
147+
`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
148+
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
149+
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
150+
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
151+
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
152+
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
153+
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
154+
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
155+
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);
156+
157+
CREATE TABLE IF NOT EXISTS t_order (
158+
order_id BIGINT NOT NULL AUTO_INCREMENT,
159+
order_type INT(11),
160+
user_id INT NOT NULL,
161+
address_id BIGINT NOT NULL,
162+
status VARCHAR(50),
163+
PRIMARY KEY (order_id)
164+
);
165+
EOSQL
166+
done
167+
```
168+
169+
### 在业务项目的 classpath 创建 `seata.conf`
170+
171+
在业务项目的 classpath 创建 `seata.conf`,内容如下,
172+
173+
```
174+
service {
175+
default.grouplist = "127.0.0.1:8091"
176+
vgroupMapping.default_tx_group = "default"
177+
}
178+
```
179+
180+
### 在业务项目的 classpath 创建 `file.conf`
181+
182+
在业务项目的 classpath 创建 `file.conf`,内容如下,
183+
184+
```
185+
client {
186+
application.id = test
187+
transaction.service.group = default_tx_group
188+
}
189+
```
190+
191+
### 在业务项目的 classpath 创建 `registry.conf`
192+
193+
在业务项目的 classpath 创建 `registry.conf`,内容如下,
194+
195+
```
196+
registry {
197+
type = "file"
198+
file {
199+
name = "file.conf"
200+
}
201+
}
202+
config {
203+
type = "file"
204+
file {
205+
name = "file.conf"
206+
}
207+
}
208+
```
209+
210+
### 在业务项目创建 ShardingSphere 配置文件
211+
212+
在业务项目引入前提条件涉及的依赖后,在业务项目的 classpath 上编写 ShardingSphere 数据源的配置文件`demo.yaml`
213+
214+
```yaml
215+
dataSources:
216+
ds_0:
217+
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
218+
driverClassName: com.mysql.cj.jdbc.Driver
219+
jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?sslMode=REQUIRED
220+
username: root
221+
password: example
222+
ds_1:
223+
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
224+
driverClassName: com.mysql.cj.jdbc.Driver
225+
jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?sslMode=REQUIRED
226+
username: root
227+
password: example
228+
ds_2:
229+
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
230+
driverClassName: com.mysql.cj.jdbc.Driver
231+
jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_2?sslMode=REQUIRED
232+
username: root
233+
password: example
234+
rules:
235+
- !SHARDING
236+
tables:
237+
t_order:
238+
actualDataNodes: ds_$->{0..2}.t_order
239+
keyGenerateStrategy:
240+
column: order_id
241+
keyGeneratorName: snowflake
242+
defaultDatabaseStrategy:
243+
standard:
244+
shardingColumn: user_id
245+
shardingAlgorithmName: inline
246+
shardingAlgorithms:
247+
inline:
248+
type: INLINE
249+
props:
250+
algorithm-expression: ds_${user_id % 2}
251+
keyGenerators:
252+
snowflake:
253+
type: SNOWFLAKE
254+
transaction:
255+
defaultType: BASE
256+
providerType: Seata
257+
```
258+
259+
### 享受集成
260+
261+
在 ShardingSphere 的数据源上可开始享受集成,
262+
263+
```java
264+
import com.zaxxer.hikari.HikariConfig;
265+
import com.zaxxer.hikari.HikariDataSource;
266+
import java.sql.Connection;
267+
import java.sql.SQLException;
268+
@SuppressWarnings({"SqlNoDataSourceInspection", "AssertWithSideEffects"})
269+
public class ExampleTest {
270+
void test() throws SQLException {
271+
HikariConfig config = new HikariConfig();
272+
config.setJdbcUrl("jdbc:shardingsphere:classpath:demo.yaml");
273+
config.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver");
274+
try (HikariDataSource dataSource = new HikariDataSource(config)) {
275+
try (Connection conn = dataSource.getConnection()) {
276+
try {
277+
conn.setAutoCommit(false);
278+
conn.createStatement().executeUpdate("INSERT INTO t_order (user_id, order_type, address_id, status) VALUES (2024, 1, 2024, 'INSERT_TEST')");
279+
conn.createStatement().executeUpdate("INSERT INTO t_order_does_not_exist (test_id_does_not_exist) VALUES (2024)");
280+
conn.commit();
281+
} catch (final SQLException ignored) {
282+
conn.rollback();
283+
} finally {
284+
conn.setAutoCommit(true);
285+
}
286+
}
287+
try (Connection conn = dataSource.getConnection()) {
288+
assert !conn.createStatement().executeQuery("SELECT * FROM t_order_item WHERE user_id = 2024").next();
289+
}
290+
}
291+
}
292+
}
293+
```
294+
131295
## 使用限制
132296

133297
ShardingSphere 的 Seata 集成不支持隔离级别。
@@ -137,7 +301,7 @@ ShardingSphere 的 Seata 集成将获取到的 Seata 全局事务置入线程的
137301
这意味着用户在使用 ShardingSphere 的 Seata 集成时,用户应避免使用 `org.apache.seata:seata-all` 的 Java API,
138302
除非用户正在混合使用 ShardingSphere 的 Seata 集成与 Seata Client 的 TCC 模式特性。
139303

140-
针对 ShardingSphere 数据源,讨论 6 种情况,
304+
针对 ShardingSphere 数据源,讨论 7 种情况,
141305

142306
1. 手动获取从 ShardingSphere 数据源创建的 `java.sql.Connection` 实例,并手动调用 `setAutoCommit()`, `commit()``rollback()` 方法,
143307
这是被允许的。
@@ -148,9 +312,13 @@ ShardingSphere 的 Seata 集成将获取到的 Seata 全局事务置入线程的
148312

149313
4. 在函数上使用 Spring Framework 的 `org.springframework.transaction.annotation.Transactional` 注解,这是被允许的。
150314

151-
5. 在函数上使用 `org.apache.seata.spring.annotation.GlobalTransactional` 注解,这是**不被允许的**。
315+
5. 手动获取从 `org.springframework.transaction.PlatformTransactionManager` 实例创建的 `org.springframework.transaction.support.TransactionTemplate` 实例,
316+
并使用 `org.springframework.transaction.support.TransactionTemplate#execute(org.springframework.transaction.support.TransactionCallback)`
317+
这是被允许的。
318+
319+
6. 在函数上使用 `org.apache.seata.spring.annotation.GlobalTransactional` 注解,这是**不被允许的**
152320

153-
6. 手动从 `org.apache.seata.tm.api.GlobalTransactionContext ` 创建 `org.apache.seata.tm.api.GlobalTransaction` 实例,
321+
7. 手动从 `org.apache.seata.tm.api.GlobalTransactionContext ` 创建 `org.apache.seata.tm.api.GlobalTransaction` 实例,
154322
调用 `org.apache.seata.tm.api.GlobalTransaction` 实例的 `begin()`, `commit()``rollback()` 方法,这是**不被允许的**
155323

156324
在使用 Spring Boot 的实际情景中,
@@ -173,7 +341,7 @@ ShardingSphere 的 Seata 集成将获取到的 Seata 全局事务置入线程的
173341
<dependency>
174342
<groupId>org.apache.seata</groupId>
175343
<artifactId>seata-spring-boot-starter</artifactId>
176-
<version>2.1.0</version>
344+
<version>2.2.0</version>
177345
<exclusions>
178346
<exclusion>
179347
<groupId>org.antlr</groupId>
@@ -378,7 +546,7 @@ public class CustomWebMvcConfigurer implements WebMvcConfigurer {
378546

379547
3. 微服务实例 `a-service``b-service` 均为 Spring Boot 微服务,但使用的 API 网关中间件阻断了所有包含 `TX_XID` 的 HTTP Header 的 HTTP 请求。
380548
用户需要考虑更改把 XID 通过服务调用传递到微服务实例 `a-service` 使用的 HTTP Header,或使用 RPC 框架把 XID 通过服务调用传递到微服务实例 `a-service`
381-
参考 https://github.com/apache/incubator-seata/tree/v2.1.0/integration
549+
参考 https://github.com/apache/incubator-seata/tree/v2.2.0/integration
382550

383551
4. 微服务实例 `a-service``b-service` 均为 Quarkus,Micronaut Framework 和 Helidon 等微服务。
384552
此情况下无法使用 Spring WebMVC HandlerInterceptor。

0 commit comments

Comments
 (0)