Account.javapackage com.ruoyi.account.domain; import lombok.Getter; import lombok.Setter; import java.util.Date; Getter Setter public class Account { private Long id; /** * 余额 */ private Double balance; private Date lastUpdateTime; }AccountMapper.javapackage com.ruoyi.account.mapper; import com.ruoyi.account.domain.Account; public interface AccountMapper { public Account selectById(Long userId); public void updateById(Account account); }AccountMapper.xml?xml version1.0 encodingUTF-8 ? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.ruoyi.account.mapper.AccountMapper resultMap typecom.ruoyi.account.domain.Account idAccountResult id propertyid columnid / result propertybalance columnbalance / result propertylastUpdateTime columnlast_update_time / /resultMap select idselectById parameterTypecom.ruoyi.account.domain.Account resultMapAccountResult select id, balance, last_update_time from account where id #{userId} /select update idupdateById parameterTypecom.ruoyi.account.domain.Account update account set balance #{balance}, last_update_time sysdate() where id #{id} /update /mapperAccountService.javapackage com.ruoyi.account.service; public interface AccountService { /** * 账户扣减 * param userId 用户 ID * param price 扣减金额 */ void reduceBalance(Long userId, Double price); }AccountServiceImpl.javapackage com.ruoyi.account.service.impl; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.baomidou.dynamic.datasource.annotation.DS; import com.ruoyi.account.domain.Account; import com.ruoyi.account.mapper.AccountMapper; import com.ruoyi.account.service.AccountService; import io.seata.core.context.RootContext; Service public class AccountServiceImpl implements AccountService { private static final Logger log LoggerFactory.getLogger(AccountServiceImpl.class); Resource private AccountMapper accountMapper; /** * 事务传播特性设置为 REQUIRES_NEW 开启新的事务 重要一定要使用REQUIRES_NEW * 在若依的示例中事务的传播特性必须设置REQUIRES_NEW但经本人测试多服务调用事务 * 设置成默认的REQUIRED也能回滚成功 */ Override Transactional public void reduceBalance(Long userId, Double price) { log.info(ACCOUNT START); log.info(当前 XID: {}, RootContext.getXID()); Account account accountMapper.selectById(userId); Double balance account.getBalance(); log.info(下单用户{}余额为 {},商品总价为{}, userId, balance, price); if (balance price) { log.warn(用户 {} 余额不足当前余额:{}, userId, balance); throw new RuntimeException(余额不足); } log.info(开始扣减用户 {} 余额, userId); double currentBalance account.getBalance() - price; account.setBalance(currentBalance); accountMapper.updateById(account); log.info(扣减用户 {} 余额成功,扣减后用户账户余额为{}, userId, currentBalance); log.info(ACCOUNT END); } }AccountController.javapackage com.ruoyi.account.controller; import com.ruoyi.account.dto.ReduceBalanceRequest; import com.ruoyi.account.service.AccountService; import com.ruoyi.common.core.domain.R; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RestController RequestMapping(/account) public class AccountController { Autowired private AccountService accountService; PostMapping(/reduceBalance) public R reduceBalance(Validated RequestBody ReduceBalanceRequest request) { accountService.reduceBalance(request.getUserId(), request.getPrice()); return R.ok(下单成功); } }ReduceBalanceRequest.javapackage com.ruoyi.account.dto; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; Getter Setter NoArgsConstructor AllArgsConstructor public class ReduceBalanceRequest { private Long userId; private Double price; }至此账户服务就搭建好了这里主要提供一个扣减账户余额的接口。搭建商品服务同样在ruoyi-modules新建一个Moduleruoyi-product。ruoyi-product的pom.xml:project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdcom.ruoyi/groupId artifactIdruoyi-modules/artifactId version3.6.6/version /parent artifactIdruoyi-product/artifactId packagingjar/packaging nameruoyi-product/name urlhttp://maven.apache.org/url properties project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties dependencies !-- SpringCloud Alibaba Nacos -- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency !-- SpringCloud Alibaba Nacos Config -- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-config/artifactId /dependency !-- SpringCloud Alibaba Sentinel -- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-sentinel/artifactId /dependency !-- SpringBoot Actuator -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency !-- Mysql Connector -- dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId /dependency !-- RuoYi Common DataSource -- dependency groupIdcom.ruoyi/groupId artifactIdruoyi-common-datasource/artifactId /dependency !-- RuoYi Common DataScope -- dependency groupIdcom.ruoyi/groupId artifactIdruoyi-common-datascope/artifactId /dependency !-- RuoYi Common Log -- dependency groupIdcom.ruoyi/groupId artifactIdruoyi-common-log/artifactId /dependency !-- RuoYi Common Swagger -- dependency groupIdcom.ruoyi/groupId artifactIdruoyi-common-swagger/artifactId /dependency !-- SpringBoot Seata -- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-seata/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId /dependency /dependencies build finalName${project.artifactId}/finalName plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId executions execution goals goalrepackage/goal /goals /execution /executions /plugin /plugins /build /projectruoyi-product的bootstrap.yml:# Tomcat server: port: 10302 # Spring spring: application: # 应用名称 name: ruoyi-product profiles: # 环境配置 active: dev cloud: nacos: discovery: # 服务注册地址 server-addr: 127.0.0.1:8848 config: # 配置中心地址 server-addr: 127.0.0.1:8848 # 配置文件格式 file-extension: yml # 共享配置 shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} seata: enabled: true # Seata 应用编号默认为 ${spring.application.name} application-id: ${spring.application.name} # Seata 事务组编号用于 TC 集群名 tx-service-group: ${spring.application.name}-group # 关闭自动代理 enable-auto-data-source-proxy: false # 服务配置项 service: # 虚拟组和分组的映射 vgroup-mapping: ruoyi-product-group: default config: type: nacos nacos: serverAddr: 127.0.0.1:8848 group: SEATA_GROUP namespace: dataId: seataServer.properties registry: type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 namespace: