diff --git a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSpringTransaction.java b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSpringTransaction.java
index f15d2e68..c29d74b6 100644
--- a/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSpringTransaction.java
+++ b/mybatis-flex-spring/src/main/java/com/mybatisflex/spring/FlexSpringTransaction.java
@@ -88,6 +88,6 @@ public class FlexSpringTransaction implements Transaction {
@Override
public Integer getTimeout() throws SQLException {
- return getConnection().getNetworkTimeout();
+ return null;
}
}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/config/RestTemplateConfig.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/config/RestTemplateConfig.java
new file mode 100644
index 00000000..c5605f4c
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/config/RestTemplateConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.acount.accountservice.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ return restTemplate;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/controller/AccountController.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/controller/AccountController.java
new file mode 100644
index 00000000..4b7f2250
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/controller/AccountController.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.acount.accountservice.controller;
+
+import io.seata.core.context.RootContext;
+import java.math.BigDecimal;
+import mybatisflex.test.acount.accountservice.service.AccountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class AccountController {
+
+ @Autowired
+ AccountService accountService;
+
+ @GetMapping
+ public void debit(@RequestParam String userId, @RequestParam BigDecimal orderMoney) {
+ System.out.println("account XID " + RootContext.getXID());
+ accountService.debit(userId, orderMoney);
+ }
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/Account.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/Account.java
new file mode 100644
index 00000000..9f36d497
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/Account.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.acount.accountservice.persistence;
+
+import java.math.BigDecimal;
+
+public class Account {
+ private Integer id;
+
+ private String userId;
+
+ private BigDecimal money;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public BigDecimal getMoney() {
+ return money;
+ }
+
+ public void setMoney(BigDecimal money) {
+ this.money = money;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/AccountMapper.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/AccountMapper.java
new file mode 100644
index 00000000..282c10f5
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/persistence/AccountMapper.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.acount.accountservice.persistence;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface AccountMapper {
+
+ Account selectByUserId(@Param("userId") String userId);
+
+ int updateById(Account record);
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/service/AccountService.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/service/AccountService.java
new file mode 100644
index 00000000..14fbfa26
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/java/mybatisflex/test/acount/accountservice/service/AccountService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.acount.accountservice.service;
+
+import java.math.BigDecimal;
+import mybatisflex.test.acount.accountservice.persistence.Account;
+import mybatisflex.test.acount.accountservice.persistence.AccountMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class AccountService {
+
+ private static final String ERROR_USER_ID = "1002";
+
+ @Autowired
+ private AccountMapper accountMapper;
+
+ public void debit(String userId, BigDecimal num) {
+ Account account = accountMapper.selectByUserId(userId);
+ account.setMoney(account.getMoney().subtract(num));
+ accountMapper.updateById(account);
+
+ if (ERROR_USER_ID.equals(userId)) {
+ throw new RuntimeException("account branch exception");
+ }
+ }
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/application.yml
new file mode 100755
index 00000000..62c571bf
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/application.yml
@@ -0,0 +1,129 @@
+server:
+ port: 8083
+mybatis-flex:
+ seata-config:
+ enable: true #启动seata
+ seata-mode: XA #xa或者ta
+ datasource:
+ accountdb:
+ url: jdbc:mysql://127.0.0.1:3306/db_account
+ username: root
+ password: 131496
+spring:
+ main:
+ allow-circular-references: true
+#spring:
+# datasource:
+# type: com.alibaba.druid.pool.DruidDataSource
+# driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/db_account?useSSL=false&serverTimezone=UTC
+# username: root
+# password: 131496
+seata:
+ enabled: true
+ application-id: account-service
+ tx-service-group: my_test_tx_group
+ enable-auto-data-source-proxy: false
+ #use-jdk-proxy: false
+ client:
+ rm:
+ async-commit-buffer-limit: 1000
+ report-retry-count: 5
+ table-meta-check-enable: false
+ report-success-enable: false
+ lock:
+ retry-interval: 10
+ retry-times: 30
+ retry-policy-branch-rollback-on-conflict: true
+ tm:
+ commit-retry-count: 5
+ rollback-retry-count: 5
+ undo:
+ data-validation: true
+ log-serialization: jackson
+ log-table: undo_log
+ log:
+ exceptionRate: 100
+ service:
+ vgroup-mapping:
+ my_test_tx_group: default
+ grouplist:
+ default: 127.0.0.1:8091
+ #enable-degrade: false
+ #disable-global-transaction: false
+ transport:
+ shutdown:
+ wait: 3
+ thread-factory:
+ boss-thread-prefix: NettyBoss
+ worker-thread-prefix: NettyServerNIOWorker
+ server-executor-thread-prefix: NettyServerBizHandler
+ share-boss-worker: false
+ client-selector-thread-prefix: NettyClientSelector
+ client-selector-thread-size: 1
+ client-worker-thread-prefix: NettyClientWorkerThread
+ worker-thread-size: default
+ boss-thread-size: 1
+ type: TCP
+ server: NIO
+ heartbeat: true
+ serialization: seata
+ compressor: none
+ enable-client-batch-send-request: true
+ config:
+ type: file
+ consul:
+ server-addr: 127.0.0.1:8500
+ apollo:
+ apollo-meta: http://192.168.1.204:8801
+ app-id: seata-server
+ namespace: application
+ etcd3:
+ server-addr: http://localhost:2379
+ nacos:
+ namespace:
+ serverAddr: localhost
+ group: SEATA_GROUP
+ zk:
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
+ registry:
+ type: file
+ consul:
+ cluster: default
+ server-addr: 127.0.0.1:8500
+ etcd3:
+ cluster: default
+ serverAddr: http://localhost:2379
+ eureka:
+ application: default
+ weight: 1
+ service-url: http://localhost:8761/eureka
+ nacos:
+ cluster: default
+ server-addr: localhost
+ namespace:
+ redis:
+ server-addr: localhost:6379
+ db: 0
+ password:
+ cluster: default
+ timeout: 0
+ sofa:
+ server-addr: 127.0.0.1:9603
+ application: default
+ region: DEFAULT_ZONE
+ datacenter: DefaultDataCenter
+ cluster: default
+ group: SEATA_GROUP
+ addressWaitTime: 3000
+ zk:
+ cluster: default
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/mapper/AccountMapper.xml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/mapper/AccountMapper.xml
new file mode 100644
index 00000000..b5f265b5
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/account-service/src/main/resources/mapper/AccountMapper.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ update account_tbl
+ set money = #{money,jdbcType=DECIMAL}
+ where id = #{id}
+
+
+
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/OrderClient.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/OrderClient.java
new file mode 100644
index 00000000..d02e0c55
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/OrderClient.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.businessservice.client;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class OrderClient {
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public void create(String userId, String commodityCode, int orderCount) {
+ String url = "http://127.0.0.1:8082/api/order/debit?userId=" + userId + "&commodityCode=" + commodityCode
+ + "&count=" + orderCount;
+ try {
+ restTemplate.getForEntity(url, Void.class);
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("create url %s ,error:", url));
+ }
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/StockClient.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/StockClient.java
new file mode 100644
index 00000000..00897bec
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/client/StockClient.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.businessservice.client;
+
+import io.seata.core.context.RootContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class StockClient {
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public void deduct(String commodityCode, int orderCount) {
+ System.out.println("business to stock " + RootContext.getXID());
+ String url = "http://127.0.0.1:8081/api/stock/deduct?commodityCode=" + commodityCode + "&count=" + orderCount;
+ try {
+ restTemplate.getForEntity(url, Void.class);
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("deduct url %s ,error:",url),e);
+ }
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/config/RestTemplateConfig.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/config/RestTemplateConfig.java
new file mode 100644
index 00000000..ef16cb29
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/config/RestTemplateConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.businessservice.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ return restTemplate;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/controller/BusinessController.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/controller/BusinessController.java
new file mode 100644
index 00000000..5c66fb0b
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/controller/BusinessController.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.businessservice.controller;
+
+import javax.servlet.http.HttpServletRequest;
+import mybatisflex.test.businessservice.service.BusinessService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("/api/business")
+@RestController
+public class BusinessController {
+
+ @Autowired
+ private BusinessService businessService;
+
+ /**
+ * 购买下单,模拟全局事务提交
+ *
+ * @return
+ */
+ @RequestMapping("/purchase/commit")
+ public Boolean purchaseCommit(HttpServletRequest request) {
+ businessService.purchase("1001", "2001", 1);
+ return true;
+ }
+
+ /**
+ * 购买下单,模拟全局事务回滚
+ *
+ * @return
+ */
+ @RequestMapping("/purchase/rollback")
+ public Boolean purchaseRollback() {
+ try {
+ businessService.purchase("1002", "2001", 1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/service/BusinessService.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/service/BusinessService.java
new file mode 100644
index 00000000..6a74f0e8
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/java/mybatisflex/test/businessservice/service/BusinessService.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.businessservice.service;
+
+import io.seata.core.context.RootContext;
+import io.seata.spring.annotation.GlobalTransactional;
+import mybatisflex.test.businessservice.client.OrderClient;
+import mybatisflex.test.businessservice.client.StockClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class BusinessService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(BusinessService.class);
+
+ @Autowired
+ private StockClient stockClient;
+ @Autowired
+ private OrderClient orderClient;
+
+ /**
+ * 减库存,下订单
+ *
+ * @param userId
+ * @param commodityCode
+ * @param orderCount
+ */
+ @GlobalTransactional
+ public void purchase(String userId, String commodityCode, int orderCount) {
+ LOGGER.info("purchase begin ... xid: " + RootContext.getXID());
+ stockClient.deduct(commodityCode, orderCount);
+ orderClient.create(userId, commodityCode, orderCount);
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/resources/application.yml
new file mode 100755
index 00000000..173f96c5
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/business-service/src/main/resources/application.yml
@@ -0,0 +1,113 @@
+server:
+ port: 8084
+spring:
+ main:
+ allow-circular-references: true
+seata:
+ enabled: true
+ application-id: business-service
+ tx-service-group: my_test_tx_group
+ enable-auto-data-source-proxy: false
+ #use-jdk-proxy: false
+ client:
+ rm:
+ async-commit-buffer-limit: 1000
+ report-retry-count: 5
+ table-meta-check-enable: false
+ report-success-enable: false
+ lock:
+ retry-interval: 10
+ retry-times: 30
+ retry-policy-branch-rollback-on-conflict: true
+ tm:
+ commit-retry-count: 5
+ rollback-retry-count: 5
+ undo:
+ data-validation: true
+ log-serialization: jackson
+ log-table: undo_log
+ log:
+ exceptionRate: 100
+ service:
+ vgroup-mapping:
+ my_test_tx_group: default
+ grouplist:
+ default: 127.0.0.1:8091
+ #enable-degrade: false
+ #disable-global-transaction: false
+ transport:
+ shutdown:
+ wait: 3
+ thread-factory:
+ boss-thread-prefix: NettyBoss
+ worker-thread-prefix: NettyServerNIOWorker
+ server-executor-thread-prefix: NettyServerBizHandler
+ share-boss-worker: false
+ client-selector-thread-prefix: NettyClientSelector
+ client-selector-thread-size: 1
+ client-worker-thread-prefix: NettyClientWorkerThread
+ worker-thread-size: default
+ boss-thread-size: 1
+ type: TCP
+ server: NIO
+ heartbeat: true
+ serialization: seata
+ compressor: none
+ enable-client-batch-send-request: true
+ config:
+ type: file
+ consul:
+ server-addr: 127.0.0.1:8500
+ apollo:
+ apollo-meta: http://192.168.1.204:8801
+ app-id: seata-server
+ namespace: application
+ etcd3:
+ server-addr: http://localhost:2379
+ nacos:
+ namespace:
+ serverAddr: localhost
+ group: SEATA_GROUP
+ zk:
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
+ registry:
+ type: file
+ consul:
+ cluster: default
+ server-addr: 127.0.0.1:8500
+ etcd3:
+ cluster: default
+ serverAddr: http://localhost:2379
+ eureka:
+ application: default
+ weight: 1
+ service-url: http://localhost:8761/eureka
+ nacos:
+ cluster: default
+ server-addr: localhost
+ namespace:
+ redis:
+ server-addr: localhost:6379
+ db: 0
+ password:
+ cluster: default
+ timeout: 0
+ sofa:
+ server-addr: 127.0.0.1:9603
+ application: default
+ region: DEFAULT_ZONE
+ datacenter: DefaultDataCenter
+ cluster: default
+ group: SEATA_GROUP
+ addressWaitTime: 3000
+ zk:
+ cluster: default
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/config/SeataRestTemplateAutoConfiguration.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/config/SeataRestTemplateAutoConfiguration.java
new file mode 100644
index 00000000..5749ff4c
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/config/SeataRestTemplateAutoConfiguration.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.commonservice.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import mybatisflex.test.commonservice.interceptor.SeataRestTemplateInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class SeataRestTemplateAutoConfiguration {
+ @Autowired(required = false)
+ private Collection restTemplates;
+ @Autowired
+ private SeataRestTemplateInterceptor seataRestTemplateInterceptor;
+
+ public SeataRestTemplateAutoConfiguration() {
+ }
+
+ @Bean
+ public SeataRestTemplateInterceptor seataRestTemplateInterceptor() {
+ return new SeataRestTemplateInterceptor();
+ }
+
+ @PostConstruct
+ public void init() {
+ if (this.restTemplates != null) {
+ Iterator var1 = this.restTemplates.iterator();
+
+ while (var1.hasNext()) {
+ RestTemplate restTemplate = (RestTemplate)var1.next();
+ List interceptors = new ArrayList(restTemplate.getInterceptors());
+ interceptors.add(this.seataRestTemplateInterceptor);
+ restTemplate.setInterceptors(interceptors);
+ }
+ }
+
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/filter/SeataFilter.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/filter/SeataFilter.java
new file mode 100644
index 00000000..598d7161
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/filter/SeataFilter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.commonservice.filter;
+
+import io.seata.core.context.RootContext;
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SeataFilter implements Filter {
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
+ throws IOException, ServletException {
+ HttpServletRequest req = (HttpServletRequest)servletRequest;
+ String xid = req.getHeader(RootContext.KEY_XID.toLowerCase());
+ boolean isBind = false;
+ if (StringUtils.isNotBlank(xid)) {
+ RootContext.bind(xid);
+ isBind = true;
+ }
+ try {
+ filterChain.doFilter(servletRequest, servletResponse);
+ } finally {
+ if (isBind) {
+ RootContext.unbind();
+ }
+ }
+ }
+
+ @Override
+ public void destroy() {
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/interceptor/SeataRestTemplateInterceptor.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/interceptor/SeataRestTemplateInterceptor.java
new file mode 100644
index 00000000..6b5062d4
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/common-service/src/main/java/mybatisflex/test/commonservice/interceptor/SeataRestTemplateInterceptor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.commonservice.interceptor;
+
+import io.seata.core.context.RootContext;
+import java.io.IOException;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+import org.springframework.http.client.support.HttpRequestWrapper;
+import org.springframework.stereotype.Component;
+
+
+public class SeataRestTemplateInterceptor implements ClientHttpRequestInterceptor {
+ public SeataRestTemplateInterceptor() {
+ }
+
+ public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes,
+ ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
+ HttpRequestWrapper requestWrapper = new HttpRequestWrapper(httpRequest);
+ String xid = RootContext.getXID();
+ if (StringUtils.isNotEmpty(xid)) {
+ requestWrapper.getHeaders().add(RootContext.KEY_XID, xid);
+ }
+
+ return clientHttpRequestExecution.execute(requestWrapper, bytes);
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/client/AccountClient.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/client/AccountClient.java
new file mode 100644
index 00000000..e3d5167b
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/client/AccountClient.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.client;
+
+import java.math.BigDecimal;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class AccountClient {
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public void debit(String userId, BigDecimal orderMoney) {
+ String url = "http://127.0.0.1:8083?userId=" + userId + "&orderMoney=" + orderMoney;
+ try {
+ restTemplate.getForEntity(url, Void.class);
+ } catch (Exception e) {
+ throw new RuntimeException(String.format("debit url %s ,error:",url),e);
+ }
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/config/RestTemplateConfig.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/config/RestTemplateConfig.java
new file mode 100644
index 00000000..62e68996
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/config/RestTemplateConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ return restTemplate;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/controller/OrderController.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/controller/OrderController.java
new file mode 100644
index 00000000..948e3659
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/controller/OrderController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.controller;
+
+import io.seata.core.context.RootContext;
+import mybatisflex.test.orderservice.service.OrderService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("/api/order")
+@RestController
+public class OrderController {
+
+ @Autowired
+ OrderService orderService;
+
+ @GetMapping(value = "/debit")
+ public void debit(@RequestParam String userId, @RequestParam String commodityCode, @RequestParam Integer count) {
+ System.out.println("order XID " + RootContext.getXID());
+ orderService.create(userId, commodityCode, count);
+ }
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/Order.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/Order.java
new file mode 100644
index 00000000..4e800413
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/Order.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.persistence;
+
+import java.math.BigDecimal;
+
+public class Order {
+ private Integer id;
+
+ private String userId;
+
+ private String commodityCode;
+
+ private Integer count;
+
+ private BigDecimal money;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getCommodityCode() {
+ return commodityCode;
+ }
+
+ public void setCommodityCode(String commodityCode) {
+ this.commodityCode = commodityCode;
+ }
+
+ public Integer getCount() {
+ return count;
+ }
+
+ public void setCount(Integer count) {
+ this.count = count;
+ }
+
+ public BigDecimal getMoney() {
+ return money;
+ }
+
+ public void setMoney(BigDecimal money) {
+ this.money = money;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/OrderMapper.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/OrderMapper.java
new file mode 100644
index 00000000..e6259c41
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/persistence/OrderMapper.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.persistence;
+
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface OrderMapper {
+
+ int insert(Order record);
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/service/OrderService.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/service/OrderService.java
new file mode 100644
index 00000000..5f774b8b
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/java/mybatisflex/test/orderservice/service/OrderService.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.orderservice.service;
+
+
+import java.math.BigDecimal;
+import mybatisflex.test.orderservice.client.AccountClient;
+import mybatisflex.test.orderservice.persistence.Order;
+import mybatisflex.test.orderservice.persistence.OrderMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class OrderService {
+
+ @Autowired
+ private AccountClient accountClient;
+ @Autowired
+ private OrderMapper orderMapper;
+
+ public void create(String userId, String commodityCode, Integer count) {
+ BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
+ Order order = new Order();
+ order.setUserId(userId);
+ order.setCommodityCode(commodityCode);
+ order.setCount(count);
+ order.setMoney(orderMoney);
+
+ orderMapper.insert(order);
+
+ accountClient.debit(userId, orderMoney);
+
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/application.yml
new file mode 100755
index 00000000..3cac9a3c
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/application.yml
@@ -0,0 +1,129 @@
+server:
+ port: 8082
+mybatis-flex:
+ seata-config:
+ enable: true #启动seata
+ seata-mode: XA #xa或者ta
+ datasource:
+ orderdb:
+ url: jdbc:mysql://127.0.0.1:3306/db_order
+ username: root
+ password: 131496
+spring:
+ main:
+ allow-circular-references: true
+#spring:
+# datasource:
+# type: com.alibaba.druid.pool.DruidDataSource
+# driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/db_order?useSSL=false&serverTimezone=UTC
+# username: root
+# password: 131496
+seata:
+ enabled: true
+ application-id: order-service
+ tx-service-group: my_test_tx_group
+ enable-auto-data-source-proxy: false
+ #use-jdk-proxy: false
+ client:
+ rm:
+ async-commit-buffer-limit: 1000
+ report-retry-count: 5
+ table-meta-check-enable: false
+ report-success-enable: false
+ lock:
+ retry-interval: 10
+ retry-times: 30
+ retry-policy-branch-rollback-on-conflict: true
+ tm:
+ commit-retry-count: 5
+ rollback-retry-count: 5
+ undo:
+ data-validation: true
+ log-serialization: jackson
+ log-table: undo_log
+ log:
+ exceptionRate: 100
+ service:
+ vgroup-mapping:
+ my_test_tx_group: default
+ grouplist:
+ default: 127.0.0.1:8091
+ #enable-degrade: false
+ #disable-global-transaction: false
+ transport:
+ shutdown:
+ wait: 3
+ thread-factory:
+ boss-thread-prefix: NettyBoss
+ worker-thread-prefix: NettyServerNIOWorker
+ server-executor-thread-prefix: NettyServerBizHandler
+ share-boss-worker: false
+ client-selector-thread-prefix: NettyClientSelector
+ client-selector-thread-size: 1
+ client-worker-thread-prefix: NettyClientWorkerThread
+ worker-thread-size: default
+ boss-thread-size: 1
+ type: TCP
+ server: NIO
+ heartbeat: true
+ serialization: seata
+ compressor: none
+ enable-client-batch-send-request: true
+ config:
+ type: file
+ consul:
+ server-addr: 127.0.0.1:8500
+ apollo:
+ apollo-meta: http://192.168.1.204:8801
+ app-id: seata-server
+ namespace: application
+ etcd3:
+ server-addr: http://localhost:2379
+ nacos:
+ namespace:
+ serverAddr: localhost
+ group: SEATA_GROUP
+ zk:
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
+ registry:
+ type: file
+ consul:
+ cluster: default
+ server-addr: 127.0.0.1:8500
+ etcd3:
+ cluster: default
+ serverAddr: http://localhost:2379
+ eureka:
+ application: default
+ weight: 1
+ service-url: http://localhost:8761/eureka
+ nacos:
+ cluster: default
+ server-addr: localhost
+ namespace:
+ redis:
+ server-addr: localhost:6379
+ db: 0
+ password:
+ cluster: default
+ timeout: 0
+ sofa:
+ server-addr: 127.0.0.1:9603
+ application: default
+ region: DEFAULT_ZONE
+ datacenter: DefaultDataCenter
+ cluster: default
+ group: SEATA_GROUP
+ addressWaitTime: 3000
+ zk:
+ cluster: default
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/mapper/OrderMapper.xml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/mapper/OrderMapper.xml
new file mode 100644
index 00000000..b052cac6
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/order-service/src/main/resources/mapper/OrderMapper.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ insert into order_tbl (user_id, commodity_code, count, money)
+ values (#{userId,jdbcType=VARCHAR}, #{commodityCode,jdbcType=VARCHAR}, #{count,jdbcType=INTEGER},
+ #{money,jdbcType=DECIMAL})
+
+
+
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/sql/all_in_one.sql b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/sql/all_in_one.sql
new file mode 100644
index 00000000..e4a1f88e
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/sql/all_in_one.sql
@@ -0,0 +1,97 @@
+# Account
+DROP SCHEMA IF EXISTS db_account;
+CREATE SCHEMA db_account;
+USE db_account;
+
+CREATE TABLE `account_tbl`
+(
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `user_id` VARCHAR(255) DEFAULT NULL,
+ `money` INT(11) DEFAULT 0,
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8;
+
+INSERT INTO account_tbl (id, user_id, money)
+VALUES (1, '1001', 10000);
+INSERT INTO account_tbl (id, user_id, money)
+VALUES (2, '1002', 10000);
+
+CREATE TABLE `undo_log`
+(
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `branch_id` bigint(20) NOT NULL,
+ `xid` varchar(100) NOT NULL,
+ `context` varchar(128) NOT NULL,
+ `rollback_info` longblob NOT NULL,
+ `log_status` int(11) NOT NULL,
+ `log_created` datetime NOT NULL,
+ `log_modified` datetime NOT NULL,
+ `ext` varchar(100) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+# Order
+DROP SCHEMA IF EXISTS db_order;
+CREATE SCHEMA db_order;
+USE db_order;
+
+CREATE TABLE `order_tbl`
+(
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `user_id` VARCHAR(255) DEFAULT NULL,
+ `commodity_code` VARCHAR(255) DEFAULT NULL,
+ `count` INT(11) DEFAULT '0',
+ `money` INT(11) DEFAULT '0',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8;
+
+CREATE TABLE `undo_log`
+(
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `branch_id` bigint(20) NOT NULL,
+ `xid` varchar(100) NOT NULL,
+ `context` varchar(128) NOT NULL,
+ `rollback_info` longblob NOT NULL,
+ `log_status` int(11) NOT NULL,
+ `log_created` datetime NOT NULL,
+ `log_modified` datetime NOT NULL,
+ `ext` varchar(100) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+# stock
+DROP SCHEMA IF EXISTS db_stock;
+CREATE SCHEMA db_stock;
+USE db_stock;
+
+CREATE TABLE `stock_tbl`
+(
+ `id` INT(11) NOT NULL AUTO_INCREMENT,
+ `commodity_code` VARCHAR(255) DEFAULT NULL,
+ `count` INT(11) DEFAULT '0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `commodity_code` (`commodity_code`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8;
+
+
+INSERT INTO stock_tbl (id, commodity_code, count)
+VALUES (1, '2001', 1000);
+
+CREATE TABLE `undo_log`
+(
+ `id` bigint(20) NOT NULL AUTO_INCREMENT,
+ `branch_id` bigint(20) NOT NULL,
+ `xid` varchar(100) NOT NULL,
+ `context` varchar(128) NOT NULL,
+ `rollback_info` longblob NOT NULL,
+ `log_status` int(11) NOT NULL,
+ `log_created` datetime NOT NULL,
+ `log_modified` datetime NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
+) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/config/RestTemplateConfig.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/config/RestTemplateConfig.java
new file mode 100644
index 00000000..6d204018
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/config/RestTemplateConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.stockservice.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+
+ @Bean
+ public RestTemplate restTemplate() {
+ RestTemplate restTemplate = new RestTemplate();
+ return restTemplate;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/controller/StockController.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/controller/StockController.java
new file mode 100644
index 00000000..2d394839
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/controller/StockController.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.stockservice.controller;
+
+import io.seata.core.context.RootContext;
+import java.sql.SQLException;
+import mybatisflex.test.stockservice.persistence.Stock;
+import mybatisflex.test.stockservice.service.StockService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("/api/stock")
+@RestController
+public class StockController {
+
+ @Autowired
+ StockService stockService;
+
+ @GetMapping(value = "/deduct")
+ public void deduct(@RequestParam String commodityCode, @RequestParam Integer count) throws SQLException {
+ System.out.println("stock XID " + RootContext.getXID());
+ stockService.deduct(commodityCode, count);
+ }
+
+ @GetMapping(value = "/get/{id}")
+ public Stock getById(@PathVariable("id") Integer id) {
+ return stockService.get(id);
+ }
+
+ @GetMapping(value = "/batch/update")
+ public void batchUpdateCond() {
+ try {
+ stockService.batchUpdate();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @GetMapping(value = "/batch/delete")
+ public void batchDeleteCond() {
+ try {
+ stockService.batchDelete();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/Stock.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/Stock.java
new file mode 100644
index 00000000..68605249
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/Stock.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.stockservice.persistence;
+
+public class Stock {
+ private Integer id;
+
+ private String commodityCode;
+
+ private Integer count;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getCommodityCode() {
+ return commodityCode;
+ }
+
+ public void setCommodityCode(String commodityCode) {
+ this.commodityCode = commodityCode;
+ }
+
+ public Integer getCount() {
+ return count;
+ }
+
+ public void setCount(Integer count) {
+ this.count = count;
+ }
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/StockMapper.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/StockMapper.java
new file mode 100644
index 00000000..f8225297
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/persistence/StockMapper.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.stockservice.persistence;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+@Mapper
+public interface StockMapper {
+
+ Stock selectById(@Param("id") Integer id);
+
+ Stock findByCommodityCode(@Param("commodityCode") String commodityCode);
+
+ int updateById(Stock record);
+
+ void insert(Stock record);
+
+ void insertBatch(List records);
+
+ int updateBatch(@Param("list") List ids, @Param("commodityCode") String commodityCode);
+}
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/service/StockService.java b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/service/StockService.java
new file mode 100644
index 00000000..0c603dfc
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/java/mybatisflex/test/stockservice/service/StockService.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1999-2021 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 mybatisflex.test.stockservice.service;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import javax.sql.DataSource;
+import io.seata.spring.annotation.GlobalLock;
+import io.seata.spring.annotation.GlobalTransactional;
+import mybatisflex.test.stockservice.persistence.Stock;
+import mybatisflex.test.stockservice.persistence.StockMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class StockService {
+
+ @Autowired
+ private StockMapper stockMapper;
+ @Autowired
+ private DataSource dataSource;
+
+ public void deduct(String commodityCode, int count) {
+ //There is a latent isolation problem here.
+ //I hope that users can solve it and deepen their understanding of seata isolation.
+ //At the bottom I will put a reference solution.
+ Stock stock = stockMapper.findByCommodityCode(commodityCode);
+ stock.setCount(stock.getCount() - count);
+ stockMapper.updateById(stock);
+ }
+
+ @GlobalLock
+ public Stock get(Integer id) {
+ return stockMapper.selectById(id);
+ }
+
+ /**
+ * 0.8.0 release
+ *
+ * @throws SQLException
+ */
+ @GlobalTransactional
+ public void batchUpdate() throws SQLException {
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+ try {
+ connection = dataSource.getConnection();
+ connection.setAutoCommit(false);
+ String sql = "update stock_tbl set count = ?" + " where id = ? and commodity_code = ?";
+ preparedStatement = connection.prepareStatement(sql);
+ preparedStatement.setInt(1, 100);
+ preparedStatement.setLong(2, 1);
+ preparedStatement.setString(3, "2001");
+ preparedStatement.addBatch();
+ preparedStatement.setInt(1, 200);
+ preparedStatement.setLong(2, 2);
+ preparedStatement.setString(3, "2002");
+ preparedStatement.addBatch();
+ preparedStatement.setInt(1, 300);
+ preparedStatement.setLong(2, 3);
+ preparedStatement.setString(3, "2003");
+ preparedStatement.addBatch();
+ preparedStatement.executeBatch();
+ connection.commit();
+ System.out.println(1 / 0);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ connection.close();
+ preparedStatement.close();
+ }
+ }
+
+ /**
+ * 0.8.0 release
+ *
+ * @throws SQLException
+ */
+ @GlobalTransactional
+ public void batchDelete() throws SQLException {
+ Connection connection = null;
+ PreparedStatement preparedStatement = null;
+ try {
+ connection = dataSource.getConnection();
+ connection.setAutoCommit(false);
+ String sql = "delete from stock_tbl where count = ? and commodity_code = ?";
+ preparedStatement = connection.prepareStatement(sql);
+ preparedStatement.setInt(1, 11);
+ preparedStatement.setString(2, "2001");
+ preparedStatement.addBatch();
+ preparedStatement.setInt(1, 22);
+ preparedStatement.setString(2, "2002");
+ preparedStatement.addBatch();
+ preparedStatement.setInt(1, 33);
+ preparedStatement.setString(2, "2003");
+ preparedStatement.addBatch();
+ preparedStatement.executeBatch();
+ connection.commit();
+ System.out.println(1 / 0);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ connection.close();
+ preparedStatement.close();
+ }
+ }
+}
+
+/*
+reference solution:
+ @Transactional
+ public void deduct(String commodityCode, int count) {
+ //select + for update
+ Stock stock = stockMapper.findByCommodityCode(commodityCode);
+ stock.setCount(stock.getCount() - count);
+ stockMapper.updateById(stock);
+ }
+ 1.select for update,refer https://seata.io/zh-cn/docs/overview/faq.html#4
+ 2.(optional)use @Transactional,keep X locks held until connection submission
+*/
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/application.yml
new file mode 100755
index 00000000..86474919
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/application.yml
@@ -0,0 +1,129 @@
+server:
+ port: 8081
+mybatis-flex:
+ seata-config:
+ enable: true #启动seata
+ seata-mode: XA #xa或者ta
+ datasource:
+ stockdb:
+ url: jdbc:mysql://127.0.0.1:3306/db_stock
+ username: root
+ password: 131496
+#spring:
+# datasource:
+# type: com.alibaba.druid.pool.DruidDataSource
+# driver-class-name: com.mysql.jdbc.Driver
+# url: jdbc:mysql://127.0.0.1:3306/db_stock?useSSL=false&serverTimezone=UTC
+# username: root
+# password: 131496
+spring:
+ main:
+ allow-circular-references: true
+seata:
+ enabled: true
+ application-id: stock-service
+ tx-service-group: my_test_tx_group
+ enable-auto-data-source-proxy: false
+ #use-jdk-proxy: false
+ client:
+ rm:
+ async-commit-buffer-limit: 1000
+ report-retry-count: 5
+ table-meta-check-enable: false
+ report-success-enable: false
+ lock:
+ retry-interval: 10
+ retry-times: 30
+ retry-policy-branch-rollback-on-conflict: true
+ tm:
+ commit-retry-count: 5
+ rollback-retry-count: 5
+ undo:
+ data-validation: true
+ log-serialization: jackson
+ log-table: undo_log
+ log:
+ exceptionRate: 100
+ service:
+ vgroup-mapping:
+ my_test_tx_group: default
+ grouplist:
+ default: 127.0.0.1:8091
+ #enable-degrade: false
+ #disable-global-transaction: false
+ transport:
+ shutdown:
+ wait: 3
+ thread-factory:
+ boss-thread-prefix: NettyBoss
+ worker-thread-prefix: NettyServerNIOWorker
+ server-executor-thread-prefix: NettyServerBizHandler
+ share-boss-worker: false
+ client-selector-thread-prefix: NettyClientSelector
+ client-selector-thread-size: 1
+ client-worker-thread-prefix: NettyClientWorkerThread
+ worker-thread-size: default
+ boss-thread-size: 1
+ type: TCP
+ server: NIO
+ heartbeat: true
+ serialization: seata
+ compressor: none
+ enable-client-batch-send-request: true
+ config:
+ type: file
+ consul:
+ server-addr: 127.0.0.1:8500
+ apollo:
+ apollo-meta: http://192.168.1.204:8801
+ app-id: seata-server
+ namespace: application
+ etcd3:
+ server-addr: http://localhost:2379
+ nacos:
+ namespace:
+ serverAddr: localhost
+ group: SEATA_GROUP
+ zk:
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
+ registry:
+ type: file
+ consul:
+ cluster: default
+ server-addr: 127.0.0.1:8500
+ etcd3:
+ cluster: default
+ serverAddr: http://localhost:2379
+ eureka:
+ application: default
+ weight: 1
+ service-url: http://localhost:8761/eureka
+ nacos:
+ cluster: default
+ server-addr: localhost
+ namespace:
+ redis:
+ server-addr: localhost:6379
+ db: 0
+ password:
+ cluster: default
+ timeout: 0
+ sofa:
+ server-addr: 127.0.0.1:9603
+ application: default
+ region: DEFAULT_ZONE
+ datacenter: DefaultDataCenter
+ cluster: default
+ group: SEATA_GROUP
+ addressWaitTime: 3000
+ zk:
+ cluster: default
+ server-addr: 127.0.0.1:2181
+ session-timeout: 6000
+ connect-timeout: 2000
+ username: ""
+ password: ""
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/mapper/StorageMapper.xml b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/mapper/StorageMapper.xml
new file mode 100644
index 00000000..9fd9327a
--- /dev/null
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata-demo/stock-service/src/main/resources/mapper/StorageMapper.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ update stock_tbl
+ set count = #{count,jdbcType=INTEGER}
+ WHERE id = #{id}
+
+
+
+ insert into stock_tbl (commodity_code, count)
+ values (#{commodityCode,jdbcType=VARCHAR}, #{count,jdbcType=INTEGER})
+
+
+
+ insert into stock_tbl (commodity_code, count)
+ values
+
+ (#{item.commodityCode,jdbcType=VARCHAR}, #{item.count,jdbcType=INTEGER})
+
+
+
+
+ update stock_tbl set count = 100
+ WHERE id IN
+
+ #{item}
+
+ and commodity_code = #{commodityCode,jdbcType=VARCHAR}
+
+
diff --git a/mybatis-flex-test/mybatis-flex-spring-boot-seata/pom.xml b/mybatis-flex-test/mybatis-flex-spring-boot-seata/pom.xml
index 6e1055b1..5e9742c0 100644
--- a/mybatis-flex-test/mybatis-flex-spring-boot-seata/pom.xml
+++ b/mybatis-flex-test/mybatis-flex-spring-boot-seata/pom.xml
@@ -25,7 +25,7 @@
com.mybatis-flex
mybatis-flex-codegen
- 1.5.6
+ ${mybatis-flex.version}
diff --git a/mybatis-flex-test/pom.xml b/mybatis-flex-test/pom.xml
index de11100a..c2ddea99 100644
--- a/mybatis-flex-test/pom.xml
+++ b/mybatis-flex-test/pom.xml
@@ -19,6 +19,7 @@
mybatis-flex-spring-boot-test
mybatis-flex-spring-cloud-test
mybatis-flex-spring-boot-seata
+ mybatis-flex-spring-boot-seata-demo