!248 seta事务兼容

Merge pull request !248 from life/main
This commit is contained in:
Michael Yang 2023-08-07 11:59:38 +00:00 committed by Gitee
commit 5db2e0ee5e
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
21 changed files with 870 additions and 14 deletions

View File

@ -124,3 +124,25 @@ public void doSomething(){
>假设在回滚的时候,恰好其中一个数据库出现了异常(比如 网络问题数据库崩溃此时可能只有一个数据库的数据正常回滚rollback
> 但无论如何MyBatis-Flex 都会保证在同一个 `@Transactional` 中的多个数据源,保持相同的 commit 或者 rollback 行为。
## 支持seata事务
1. 首先,先了解事务的基础(自行百度)
2. 在了解seata事务的项目 官网地址https://seata.io/zh-cn/docs
3. 然后根据官方的[快速开始](https://seata.io/zh-cn/docs/user/quickstart.html)在下载最新版的seata-server并在本地跑起一个
4. seata-server服务
5. 然后使用[mybatis-flex-test](https://gitee.com/mybatis-flex/mybatis-flex/tree/main/mybatis-flex-test)模块 下面的mybatis-flex-spring-boot-seata进行测试
>此demo只是一个纯演示的demo模仿的是[官方事例](https://github.com/seata/seata-samples/tree/master/springboot-mybatis)
进行整合微服务合并成一个多数据源进行测试当然这种方法是不提倡的seata事务并且本地多数据源的方式可能本身就存在设计思路问题可能存在过度设计此demo只是作为一个演示。
### 注意事项
>使用seata的时候必须数据源代理
`seata.enable-auto-data-source-proxy: false`
`pom`自行引入[seata-spring-boot-starter](https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter)依赖,
application.yml需要配置如下参数
1. `mybatis-flex.seata-config.enable`
配置含义seata事务是否开启true开启默认false关闭
2. `mybatis-flex.seata-config.seata-mode`
默认启动的事务类型目前只支持XA或者AT,默认AT

View File

@ -91,6 +91,12 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-rm-datasource</artifactId>
<version>1.7.0</version>
<optional>true</optional>
</dependency>
</dependencies>

View File

@ -19,7 +19,10 @@ import com.mybatisflex.core.datasource.DataSourceBuilder;
import com.mybatisflex.core.datasource.DataSourceDecipher;
import com.mybatisflex.core.datasource.DataSourceManager;
import com.mybatisflex.core.datasource.FlexDataSource;
import com.mybatisflex.spring.boot.MybatisFlexProperties.SeataConfig;
import com.mybatisflex.spring.datasource.DataSourceAdvice;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.rm.datasource.xa.DataSourceProxyXA;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.ObjectProvider;
@ -53,6 +56,8 @@ public class MultiDataSourceAutoConfiguration {
private final Map<String, Map<String, String>> dataSourceProperties;
private final SeataConfig seataConfig;
//数据源解密器
protected final DataSourceDecipher dataSourceDecipher;
@ -62,6 +67,7 @@ public class MultiDataSourceAutoConfiguration {
) {
dataSourceProperties = properties.getDatasource();
dataSourceDecipher = dataSourceDecipherProvider.getIfAvailable();
seataConfig = properties.getSeataConfig();
}
@Bean
@ -76,6 +82,13 @@ public class MultiDataSourceAutoConfiguration {
for (Map.Entry<String, Map<String, String>> entry : dataSourceProperties.entrySet()) {
DataSource dataSource = new DataSourceBuilder(entry.getValue()).build();
if (seataConfig !=null &&seataConfig.isEnable()){
if (seataConfig.getSeataMode() ==SeataMode.XA){
dataSource = new DataSourceProxyXA(dataSource);
}else {
dataSource = new DataSourceProxy(dataSource);
}
}
if (flexDataSource == null) {
flexDataSource = new FlexDataSource(entry.getKey(), dataSource);
} else {

View File

@ -122,6 +122,19 @@ public class MybatisFlexProperties {
*/
private CoreConfiguration configuration;
/**
* A Configuration object for seata
*/
private SeataConfig seataConfig;
public SeataConfig getSeataConfig() {
return seataConfig;
}
public void setSeataConfig(SeataConfig seataConfig) {
this.seataConfig = seataConfig;
}
public Map<String, Map<String, String>> getDatasource() {
return datasource;
}
@ -890,4 +903,38 @@ public class MybatisFlexProperties {
}
/**
* Seata 配置
*
* @author life
*/
public static class SeataConfig{
/**
* 是否开启
*/
private boolean enable = false;
/**
* 事务模式支持只支持XA或者AT
*/
private SeataMode seataMode = SeataMode.AT;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public SeataMode getSeataMode() {
return seataMode;
}
public void setSeataMode(SeataMode seataMode) {
this.seataMode = seataMode;
}
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 com.mybatisflex.spring.boot;
/**
* @author life
*/
public enum SeataMode {
XA,
AT
}

View File

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>mybatis-flex-test</artifactId>
<groupId>com.mybatis-flex</groupId>
<version>1.5.6</version>
</parent>
<groupId>com.mybatisfle.test</groupId>
<artifactId>mybatis-flex-spring-boot-seata</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-flex-spring-boot-seata</name>
<description>mybatis-flex-spring-boot-seata</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
<version>${mybatis-flex.version}</version>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-codegen</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.32</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.18</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-jdbc</artifactId>-->
<!-- <version>2.7.9</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework</groupId>-->
<!-- <artifactId>spring-jdbc</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.h2database</groupId>-->
<!-- <artifactId>h2</artifactId>-->
<!-- <version>2.1.214</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.yaml</groupId>-->
<!-- <artifactId>snakeyaml</artifactId>-->
<!-- <version>1.33</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>

View File

@ -0,0 +1,15 @@
package com.mybatisfle.test.mybatisflexspringbootseata;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.mybatisfle.test.mybatisflexspringbootseata")
@SpringBootApplication
public class MybatisFlexSpringBootSeataApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisFlexSpringBootSeataApplication.class, args);
}
}

View File

@ -0,0 +1,28 @@
package com.mybatisfle.test.mybatisflexspringbootseata.controller;
import com.mybatisfle.test.mybatisflexspringbootseata.service.TestService;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@Autowired
TestService testService;
@RequestMapping("buy")
public String buy(){
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
MessageCollector collector = new ConsoleMessageCollector();
AuditManager.setMessageCollector(collector);
String flag =String.valueOf(testService.buy());
return flag;
}
}

View File

@ -0,0 +1,51 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类
*
* @author life
* @since 2023-08-03
*/
@Table(value = "account_tbl", schema = "db_account")
public class AccountTbl implements Serializable {
@Id(keyType = KeyType.Auto)
private Integer id;
private String userId;
private Integer 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 Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
}

View File

@ -0,0 +1,71 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类
*
* @author life
* @since 2023-08-03
*/
@Table(value = "order_tbl", schema = "db_order")
public class OrderTbl implements Serializable {
@Id(keyType = KeyType.Auto)
private Integer id;
private String userId;
private String commodityCode;
private Integer count;
private Integer 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 Integer getMoney() {
return money;
}
public void setMoney(Integer money) {
this.money = money;
}
}

View File

@ -0,0 +1,51 @@
package com.mybatisfle.test.mybatisflexspringbootseata.entity;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 实体类
*
* @author life
* @since 2023-08-03
*/
@Table(value = "stock_tbl", schema = "db_stock")
public class StockTbl implements Serializable {
@Id(keyType = KeyType.Auto)
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;
}
}

View File

@ -0,0 +1,15 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface AccountTblMapper extends BaseMapper<AccountTbl> {
}

View File

@ -0,0 +1,15 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface OrderTblMapper extends BaseMapper<OrderTbl> {
}

View File

@ -0,0 +1,15 @@
package com.mybatisfle.test.mybatisflexspringbootseata.mapper;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
import com.mybatisflex.core.BaseMapper;
/**
* 映射层
*
* @author life
* @since 2023-08-03
*/
public interface StockTblMapper extends BaseMapper<StockTbl> {
}

View File

@ -0,0 +1,53 @@
package com.mybatisfle.test.mybatisflexspringbootseata.service;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.AccountTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.OrderTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.StockTbl;
import com.mybatisfle.test.mybatisflexspringbootseata.entity.table.AccountTblTableDef;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.AccountTblMapper;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.OrderTblMapper;
import com.mybatisfle.test.mybatisflexspringbootseata.mapper.StockTblMapper;
import com.mybatisflex.core.datasource.DataSourceKey;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TestService {
@Autowired
AccountTblMapper accountTblMapper;
@Autowired
OrderTblMapper orderTblMapper;
@Autowired
StockTblMapper stockTblMapper;
// @Transactional
public boolean buy() {
// DataSourceKey.use("accountdb");
QueryWrapper account =new QueryWrapper();
account.where(AccountTblTableDef.ACCOUNT_TBL.USER_ID.eq("1001"));
AccountTbl accountTbl = accountTblMapper.selectOneByQuery(account);
accountTbl.setMoney(accountTbl.getMoney() - 5);
accountTblMapper.update(accountTbl);
// DataSourceKey.use("stockdb");
// QueryWrapper stock = new QueryWrapper();
// stock.where("id=1");
// StockTbl stockTbl = stockTblMapper.selectOneByQuery(stock);
// stockTbl.setCount(stockTbl.getCount() - 1);
// stockTblMapper.update(stockTbl);
// DataSourceKey.use("orderdb");
// OrderTbl orderTbl = new OrderTbl();
// orderTbl.setCount(5);
// orderTbl.setMoney(5);
// orderTbl.setUserId(accountTbl.getUserId());
// orderTbl.setCount(1);
// orderTbl.setCommodityCode(stockTbl.getCommodityCode());
// orderTblMapper.insert(orderTbl);
return true;
}
}

View File

@ -0,0 +1,88 @@
package com.mybatisfle.test.mybatisflexspringbootseata.utils;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.ColumnConfig;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;
public class Codegen {
public static void main(String[] args) {
//配置数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/db_stock?characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("131496");
//创建配置内容两种风格都可以
GlobalConfig globalConfig = createGlobalConfigUseStyle1();
//GlobalConfig globalConfig = createGlobalConfigUseStyle2();
//通过 datasource globalConfig 创建代码生成器
Generator generator = new Generator(dataSource, globalConfig);
//生成代码
generator.generate();
}
public static GlobalConfig createGlobalConfigUseStyle1() {
//创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
//设置根包
globalConfig.setBasePackage("com.mybatisfle.test.mybatisflexspringbootseata");
//设置表前缀和只生成哪些表
globalConfig.setGenerateSchema("db_stock");
// globalConfig.setTablePrefix("tb_");
globalConfig.setGenerateTable("stock_tbl");
//设置生成 entity 并启用 Lombok
globalConfig.setEntityGenerateEnable(true);
globalConfig.setEntityWithLombok(true);
//设置生成 mapper
globalConfig.setMapperGenerateEnable(true);
//可以单独配置某个列
// ColumnConfig columnConfig = new ColumnConfig();
// columnConfig.setColumnName("tenant_id");
// columnConfig.setLarge(true);
// columnConfig.setVersion(true);
// globalConfig.setColumnConfig("account", columnConfig);
return globalConfig;
}
public static GlobalConfig createGlobalConfigUseStyle2() {
//创建配置内容
GlobalConfig globalConfig = new GlobalConfig();
//设置根包
globalConfig.getPackageConfig()
.setBasePackage("com.test");
//设置表前缀和只生成哪些表setGenerateTable 未配置时生成所有表
globalConfig.getStrategyConfig()
.setGenerateSchema("schema")
.setTablePrefix("tb_")
.setGenerateTable("account", "account_session");
//设置生成 entity 并启用 Lombok
globalConfig.enableEntity()
.setWithLombok(true);
//设置生成 mapper
globalConfig.enableMapper();
//可以单独配置某个列
ColumnConfig columnConfig = new ColumnConfig();
columnConfig.setColumnName("tenant_id");
columnConfig.setLarge(true);
columnConfig.setVersion(true);
globalConfig.getStrategyConfig()
.setColumnConfig("account", columnConfig);
return globalConfig;
}
}

View File

@ -0,0 +1,74 @@
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
orderdb:
url: jdbc:mysql://127.0.0.1:3306/db_order
username: root
password: 131496
stockdb:
url: jdbc:mysql://127.0.0.1:3306/db_stock
username: root
password: 131496
server:
port: 2010
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
registry:
type: file

View File

@ -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;

View File

@ -0,0 +1,13 @@
package com.mybatisfle.test.mybatisflexspringbootseata;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class MybatisFlexSpringBootSeataApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -3,11 +3,11 @@ spring:
# h2:
# console:
# enabled: true
datasource:
# driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/flex_test
username: root
password: 123456
# datasource:
## driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://localhost:3306/flex_test
# username: root
# password: 131496
# driver-class-name:
# datasource:
# driver-class-name: org.h2.Driver
@ -37,12 +37,12 @@ mybatis-flex:
# username: root
# password: 12345678
#mybatis-flex:
# datasource:
# ds1:
# url: jdbc:mysql://127.0.0.1:3306/db
# username: root
# password: 123456
# ds2:
# url: jdbc:mysql://127.0.0.1:3306/db2
# username: root
# password: 123456
datasource:
ds3333:
url: jdbc:mysql://127.0.0.1:3306/flex_test
username: root
password: 131496
ds2:
url: jdbc:mysql://127.0.0.1:3306/flex_test1
username: root
password: 131496

View File

@ -18,6 +18,7 @@
<module>mybatis-flex-spring-test</module>
<module>mybatis-flex-spring-boot-test</module>
<module>mybatis-flex-spring-cloud-test</module>
<module>mybatis-flex-spring-boot-seata</module>
</modules>
<properties>