《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC(下)

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC(下)

1.3.5.3、实现类

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    @Override
    @Transactional
    public UserInfo saveUserInfo(UserInfo userInfo) {
        userInfo.setId(IdUtils.getId());
        this.save(userInfo);
        return userInfo;
    }
    @Override
    public UserInfo getUserInfoById(Long id) {
        return this.getById(id);
    }
    @Override
    public List<UserInfo> listUserInfo() {
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.between("id",1623695688380448768L,1623695688380448769L);
        return this.list(userInfoQueryWrapper);
    }
}

1.3.6、生成ID - 雪花算法

package com.xxxx.tore.common.utils;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
/**
 * 生成各种组件ID
 */
public class IdUtils {
    /**
     * 雪花算法
     * @return
     */
    public static long getId(){
        Snowflake snowflake = IdUtil.getSnowflake(0, 0);
        long id = snowflake.nextId();
        return id;
    }
}

1.4、seata与sharding-jdbc整合

https://github.com/seata/seata-samples/tree/master/springcloud-seata-sharding-jdbc-mybatis-plus-samples

1.4.1、common中添加依赖

<!--seata依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <version>2021.0.4.0</version>
</dependency>
<!-- sharding-jdbc整合seata分布式事务-->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-transaction-base-seata-at</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2021.0.4.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>1.4.2</version>
</dependency>

1.4.2、改造account-service服务

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements AccountService {
    @Autowired
    private OrderService orderService;
    @Autowired
    private StorageService storageService;
    /**
     * 存放商品编码及其对应的价钱
     */
    private static Map<String,Integer> map = new HashMap<>();
    static {
        map.put("c001",3);
        map.put("c002",5);
        map.put("c003",10);
        map.put("c004",6);
    }
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void debit(OrderDTO orderDTO) {
        //扣减账户余额
        int calculate = this.calculate(orderDTO.getCommodityCode(), orderDTO.getCount());
        AccountDTO accountDTO = new AccountDTO(orderDTO.getUserId(), calculate);
        QueryWrapper<Account> objectQueryWrapper = new QueryWrapper<>();
        objectQueryWrapper.eq("id",1);
        objectQueryWrapper.eq(accountDTO.getUserId() != null,"user_id",accountDTO.getUserId());
        Account account = this.getOne(objectQueryWrapper);
        account.setMoney(account.getMoney() - accountDTO.getMoney());
        this.saveOrUpdate(account);
        //扣减库存
        this.storageService.deduct(new StorageDTO(null,orderDTO.getCommodityCode(),orderDTO.getCount()));
        //生成订单
        this.orderService.create(orderDTO);      
    }
    /**
     * 计算购买商品的总价钱
     * @param commodityCode
     * @param orderCount
     * @return
     */
    private int calculate(String commodityCode, int orderCount){
        //商品价钱
        Integer price = map.get(commodityCode) == null ? 0 : map.get(commodityCode);
        return price * orderCount;
    }
}

注意:调单生成调用的逻辑修改,减余额->减库存->生成订单。调用入口方法注解加上:@ShardingTransactionType(TransactionType.BASE)

1.4.3、修改business-service服务

@Service
public class BusinessServiceImpl implements BusinessService {
    @Autowired
    private OrderService orderService;
    @Autowired
    private StorageService storageService;
    @Autowired
    private AccountService accountService;
    @Override
    public void purchase(OrderDTO orderDTO) {
        //扣减账号中的钱
        accountService.debit(orderDTO);        
    }
}

1.4.4、修改order-service服务

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements OrderService {
    /**
     * 存放商品编码及其对应的价钱
     */
    private static Map<String,Integer> map = new HashMap<>();
    static {
        map.put("c001",3);
        map.put("c002",5);
        map.put("c003",10);
        map.put("c004",6);
    }
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public Order create(String userId, String commodityCode, int orderCount) {
        int orderMoney = calculate(commodityCode, orderCount);
        Order order = new Order();
        order.setUserId(userId);
        order.setCommodityCode(commodityCode);
        order.setCount(orderCount);
        order.setMoney(orderMoney);
        //保存订单
        this.save(order);
        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(true){
            throw new RuntimeException("回滚测试");
        }
        return order;
    }
    /**
     * 计算购买商品的总价钱
     * @param commodityCode
     * @param orderCount
     * @return
     */
    private int calculate(String commodityCode, int orderCount){
        //商品价钱
        Integer price = map.get(commodityCode) == null ? 0 : map.get(commodityCode);
        return price * orderCount;
    }
}

1.4.5、配置文件参考

server:
  port: 8090
spring:
  main:
    # 一个实体类对应多张表,覆盖
    allow-bean-definition-overriding: true
  shardingsphere:
    datasource:
      ds0:
        #配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=true
        password: root
        type: com.zaxxer.hikari.HikariDataSource
        username: root
      ds1:
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/account?autoReconnect=true&allowMultiQueries=true
        password: root
        type: com.zaxxer.hikari.HikariDataSource
        username: root
      # 配置数据源,给数据源起名称
      names: ds0,ds1
    props:
      sql:
        show: true
    sharding:
      tables:
        account_tbl:
          actual-data-nodes: ds0.account_tbl_${0..1}
          database-strategy:
            standard:
              preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseDBExtShardingAlgorithm
              #rangeAlgorithmClassName: com.xxxx.store.account.config.RangeDBShardingAlgorithm
              sharding-column: id
          table-strategy:
            standard:
              preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseTablesExtShardingAlgorithm
              #rangeAlgorithmClassName: com.xxxx.store.account.config.RangeTablesShardingAlgorithm
              sharding-column: id
        user_info:
          #指定 user_info 表分布情况,配置表在哪个数据库里面,表名称都是什么
          actual-data-nodes: ds0.user_info_${0..9}
          database-strategy:
            standard:
              preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseDBShardingAlgorithm
              rangeAlgorithmClassName: com.xxxx.store.account.config.RangeDBShardingAlgorithm
              sharding-column: id
          table-strategy:
            standard:
              preciseAlgorithmClassName: com.xxxx.store.account.config.PreciseTablesShardingAlgorithm
              rangeAlgorithmClassName: com.xxxx.store.account.config.RangeTablesShardingAlgorithm
              sharding-column: id
  #以上是sharding-jdbc配置
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0a
  application:
    name: account-service  #微服务名称
#  datasource:
#    username: root
#    password: root
#    url: jdbc:mysql://127.0.0.1:3306/account
#    driver-class-name: com.mysql.cj.jdbc.Driver
seata:
  enabled: true
  enable-auto-data-source-proxy: false
  application-id: account-service
  tx-service-group: default_tx_group
  service:
    vgroup-mapping:
      default_tx_group: default
    disable-global-transaction: false
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0a
      group: SEATA_GROUP
      username: nacos
      password: nacos
  config:
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: 1ff3782d-b62d-402f-8bc4-ebcf40254d0a
      group: SEATA_GROUP
      username: nacos
      password: nacos


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
9月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1354 3
|
存储 NoSQL API
微服务——MongoDB实战演练——需求分析
本文档《5-MongoDB实战演练》聚焦于某头条文章评论业务的需求分析与功能实现。基于MongoDB,需完成以下功能:1)提供基本的增删改查API;2)支持通过文章ID查询相关评论;3)实现评论点赞功能。结合实际业务场景,演示MongoDB在数据存储与操作中的应用,附带示意图帮助理解业务结构。
221 2
微服务——MongoDB实战演练——需求分析
|
7月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
11月前
|
缓存 负载均衡 监控
微服务架构下的电商API接口设计:策略、方法与实战案例
本文探讨了微服务架构下的电商API接口设计,旨在打造高效、灵活与可扩展的电商系统。通过服务拆分(如商品、订单、支付等模块)和标准化设计(RESTful或GraphQL风格),确保接口一致性与易用性。同时,采用缓存策略、负载均衡及限流技术优化性能,并借助Prometheus等工具实现监控与日志管理。微服务架构的优势在于支持敏捷开发、高并发处理和独立部署,满足电商业务快速迭代需求。未来,电商API设计将向智能化与安全化方向发展。
559 102
|
7月前
|
监控 Cloud Native Java
Spring Boot 3.x 微服务架构实战指南
🌟蒋星熠Jaxonic,技术宇宙中的星际旅人。深耕Spring Boot 3.x与微服务架构,探索云原生、性能优化与高可用系统设计。以代码为笔,在二进制星河中谱写极客诗篇。关注我,共赴技术星辰大海!(238字)
1262 2
Spring Boot 3.x 微服务架构实战指南
|
NoSQL MongoDB 微服务
微服务——MongoDB实战演练——文章评论的基本增删改查
本节介绍了文章评论的基本增删改查功能实现。首先,在`cn.itcast.article.dao`包下创建数据访问接口`CommentRepository`,继承`MongoRepository`以支持MongoDB操作。接着,在`cn.itcast.article.service`包下创建业务逻辑类`CommentService`,通过注入`CommentRepository`实现保存、更新、删除及查询评论的功能。最后,新建Junit测试类`CommentServiceTest`,对保存和查询功能进行测试,并展示测试结果截图,验证功能的正确性。
298 2
|
NoSQL Java MongoDB
微服务——MongoDB实战演练——文章评论实体类的编写
本节主要介绍文章评论实体类的编写,创建了包`cn.itcast.article.po`用于存放实体类。具体实现中,`Comment`类通过`@Document`注解映射到MongoDB的`comment`集合,包含主键、内容、发布时间、用户ID、昵称等属性,并通过`@Indexed`和`@CompoundIndex`注解添加单字段及复合索引,以提升查询效率。同时提供了Mongo命令示例,便于理解和操作。
234 2
|
9月前
|
负载均衡 监控 Java
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
在微服务架构中,高可用与稳定性至关重要。本文详解熔断、限流与负载均衡三大关键技术,结合API网关与Hystrix-Go实战,帮助构建健壮、弹性的微服务系统。
880 1
微服务稳定性三板斧:熔断、限流与负载均衡全面解析(附 Hystrix-Go 实战代码)
|
NoSQL 测试技术 MongoDB
微服务——MongoDB实战演练——MongoTemplate实现评论点赞
本节介绍如何使用MongoTemplate实现评论点赞功能。传统方法通过查询整个文档并更新所有字段,效率较低。为优化性能,采用MongoTemplate对特定字段直接操作。代码中展示了如何利用`Query`和`Update`对象构建更新逻辑,通过`update.inc(&quot;likenum&quot;)`实现点赞数递增。测试用例验证了功能的正确性,确保点赞数成功加1。
277 0
|
NoSQL 测试技术 MongoDB
微服务——MongoDB实战演练——根据上级ID查询文章评论的分页列表
本节介绍如何根据上级ID查询文章评论的分页列表,主要包括以下内容:(1)在CommentRepository中新增`findByParentid`方法,用于按父ID查询子评论分页列表;(2)在CommentService中新增`findCommentListPageByParentid`方法,封装分页逻辑;(3)提供JUnit测试用例,验证功能正确性;(4)使用Compass插入测试数据并执行测试,展示查询结果。通过这些步骤,实现对评论的高效分页查询。
230 0