seata / config 配置文件
conf
registry {
# 改成 file,不用任何注册中心
type = "file"
file {
name = "file.conf"
}
}
config {
# 配置也改成 file,不从 nacos 读
type = "file"
file {
name = "file.conf"
}
}
transport {
# 最大帧长度,单位:字节,默认 8MB=8388608,这里改成 1GB=1073741824
max-frame-size = 1073741824
}
service {
vgroupMapping.my_test_tx_group = "my_test_tx_group" # 事务组名:my_test_tx_group
default.grouplist = "127.0.0.1:8091"
}
Spring Cloud 项目配置
xml
<!-- Seata -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.6.1</version> <!-- 跟server版本一致 -->
</dependency>
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- MySQL + MyBatis/MyBatis-Plus -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
yml 配置文件
yml
# Tomcat
server:
port: 8084
#spring:
# datasource:
# url: jdbc:mysql://182.92.236.162:3306/app6_chuanpukj_c?allowZeroDates=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# username: chuanpukj
# password: 98wG5nt1yR2Qf3Af
# driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis:
# type-aliases-package: com.xinsheng.api.mapper # 指定实体类的包路径
# mapper-locations: classpath:mapper/*.xml # Mapper XML文件的位置
spring:
application:
name: base-system
redis:
host: 182.92.236.162
port: 6379
password: Xscs786786 # 如果你的Redis设置了密码
datasource:
url: jdbc:mysql://127.0.0.1:3306/app6_chuanpukj_c?allowZeroDates=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: 10
min-idle: 10
maxActive: 40
maxWait: 60000
# datasource:
# url: jdbc:mysql://182.92.236.162:3306/app6_chuanpukj_c?allowZeroDates=true&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai
# username: chuanpukj
# password: 98wG5nt1yR2Qf3Af
# driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis:
# type-aliases-package: com.xinsheng.api.mapper # 指定实体类的包路径
# mapper-locations: classpath:mapper/*.xml # Mapper XML文件的位置
# configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# Mybatis配置
mybatis:
# 搜索指定包别名
typeAliasesPackage: com.xinsheng.api.mapper
# 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
level:
com.xinsheng: debug #配置 xxx包下面所有类以debug日志级别输出
seata:
transport:
max-frame-size: 1073741824 # 跟服务端保持一致
enabled: true
application-id: order-service
tx-service-group: my_test_tx_group # 跟 file.conf 一致
service:
vgroup-mapping:
my_test_tx_group: default
grouplist:
default: 127.0.0.1:8091
每个业务库必须建 undo_log 表
sql
CREATE TABLE undo_log (
id BIGINT NOT NULL AUTO_INCREMENT,
branch_id BIGINT NOT NULL,
xid VARCHAR(128) NOT NULL,
context VARCHAR(128) NOT NULL,
rollback_info LONGBLOB NOT NULL,
log_status INT 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 DEFAULT CHARSET=utf8;
启动类加 @EnableFeignClients
java
package com.xinsheng.api;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
*引导类:SpringBoot的项目入口。
* http://localhost:8084/
*/
@SpringBootApplication
@MapperScan("com.xinsheng.api.mapper")
@EnableFeignClients
public class SystemApplication {
public static void main(String[] args) {
SpringApplication.run(SystemApplication.class,args);
System.out.println("~~启动成功!【 永不宕机 永无BUG 永不修改 】~~");
}
}
feign 类
java
package com.xinsheng.api.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "base-divide", url = "http://127.0.0.1:8085")
public interface TestFeignClient {
@GetMapping("/test1")
public String test1();
}
java
package com.xinsheng.api.config;
import cn.hutool.core.util.StrUtil;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import io.seata.core.context.RootContext;
import org.springframework.stereotype.Component;
@Component
public class SeataFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
String xid = RootContext.getXID();
if (StrUtil.isNotBlank(xid)) {
template.header(RootContext.KEY_XID, xid);
}
}
}
base-system 服务 controller
java
package com.xinsheng.api.controller;
import com.xinsheng.api.domain.EcsUsers;
import com.xinsheng.api.feign.TestFeignClient;
import com.xinsheng.api.mapper.EcsUsersMapper;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
@Slf4j
@RestController
public class T {
@Autowired
private TestFeignClient testFeignClient;
@Autowired
private EcsUsersMapper ecsUsersMapper;
@GetMapping("/test32")
@GlobalTransactional(rollbackFor = Exception.class)
public String test32(){
EcsUsers ecsUsers = new EcsUsers();
ecsUsers.setUserMoney(new BigDecimal("10"));
ecsUsers.setUserId(33813);
ecsUsersMapper.updateUserMoneyUserMoney(ecsUsers);
testFeignClient.test1();
int i = 1 / 0;
return "ok";
}
}
base-divide
java
package com.xinsheng.divide.controller;
import com.xinsheng.divide.domain.EcsUsers;
import com.xinsheng.divide.domain.EcsXinshengOrderRebateLog;
import com.xinsheng.divide.mapper.EcsUsersMapper;
import com.xinsheng.divide.mapper.EcsXinshengOrderRebateLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.List;
@RestController
public class TestController {
@Autowired
private EcsXinshengOrderRebateLogMapper ecsXinshengOrderRebateLogMapper;
@Autowired
private EcsUsersMapper ecsUsersMapper;
@GetMapping("/test2")
public String test2(){
List<EcsXinshengOrderRebateLog> ecsXinshengOrderRebateLogList = ecsXinshengOrderRebateLogMapper.queryByCreateTime();
for (EcsXinshengOrderRebateLog ecsXinshengOrderRebateLog : ecsXinshengOrderRebateLogList) {
BigDecimal paypoints = ecsXinshengOrderRebateLog.getRebateCount();
if(paypoints.compareTo(BigDecimal.ONE) > 0){
paypoints = paypoints.multiply(new BigDecimal("0.8")).setScale(2, BigDecimal.ROUND_HALF_UP);
}
EcsUsers ecsUsers = new EcsUsers();
ecsUsers.setUserId(ecsXinshengOrderRebateLog.getUserId());
ecsUsers.setPayPointsDisabled2(paypoints);
ecsUsersMapper.updateUserMoney2(ecsUsers);
}
return "ok";
}
@GetMapping("/test1")
public String test1(){
EcsUsers ecsUsers = new EcsUsers();
ecsUsers.setUserMoney(new BigDecimal("90"));
ecsUsers.setUserId(33813);
ecsUsersMapper.updateUserMoneyUserMoney(ecsUsers);
return "ok";
}
}