成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SpringBoot與ShardingSphere整合,重構高并發庫存扣減場景的分布式事務模型

開發 前端
訂單創建和庫存扣減操作必須保證原子性,避免出現超賣或欠賣的情況,利用 ShardingSphere 的分布式事務管理功能,確保跨多個數據庫的操作具有一致性。

訂單創建和庫存扣減操作必須保證原子性,避免出現超賣或欠賣的情況,利用 ShardingSphere 的分布式事務管理功能,確保跨多個數據庫的操作具有一致性。

為什么選擇ShardingSphere?

  • XA 事務支持:ShardingSphere 提供了 XA 協議的支持,確保跨多個數據庫的操作具有強一致性,即使在分布式環境下也能保持數據的一致性。
  • 柔性事務:除了 XA 事務外,ShardingSphere 還支持柔性事務解決方案,如 Saga 和 BASE 模型,以適應不同的業務場景。
  • 動態添加/刪除數據源:可以在運行時動態地添加或刪除數據源,而無需重啟應用程序,提高了系統的靈活性和可維護性。
  • SQL 解析引擎:ShardingSphere 內置了強大的 SQL 解析引擎,能夠解析和改寫 SQL 語句,使其適用于分片后的數據庫結構。
  • 透明化訪問:通過標準的 JDBC 接口訪問分片后的數據庫,無需關心底層的數據分布情況。
  • 多種部署模式:ShardingSphere 支持多種部署模式,包括代理模式和嵌入式模式。
  • 容器化支持:支持 Docker 和 Kubernetes 等容器化平臺,便于自動化部署和管理。
  • 簡化開發:通過 Spring 的事務注解(如 @Transactional),開發者可以輕松地進行事務管理,無需手動編寫復雜的事務邏輯。
  • 集成 Atomikos:Atomikos 是一個成熟的事務管理器,與 ShardingSphere 結合使用可以提供可靠的分布式事務管理能力。
  • 靈活的分片策略:可以根據不同的業務需求選擇合適的分片算法(如 INLINERANGE 等),確保數據均勻分布并優化查詢性能。
  • 支持水平分片:ShardingSphere 支持將數據按一定的規則分散到多個數據庫實例中,從而實現水平擴展。這對于處理大規模訂單和產品數據非常有效。

代碼實操

<!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring Boot Starter Data JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- MySQL Connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <!-- Lombok (optional) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- ShardingSphere JDBC Core -->
    <dependency>
        <groupId>org.apache.shardingsphere</groupId>
        <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
        <version>5.1.2</version>
    </dependency>

    <!-- Atomikos Transaction Manager -->
    <dependency>
        <groupId>com.atomikos</groupId>
        <artifactId>transactions-jta</artifactId>
        <version>5.0.13</version>
    </dependency>

application.yml

server:
  port:8080

spring:
application:
    name:sharding-demo

# 數據庫配置
spring:
shardingsphere:
    datasource:
      names:ds0,ds1
      ds0:
        type:com.zaxxer.hikari.HikariDataSource
        driver-class-name:com.mysql.cj.jdbc.Driver
        jdbc-url:jdbc:mysql://localhost:3306/db0?useSSL=false&serverTimezone=UTC
        username:root
        password:root
      ds1:
        type:com.zaxxer.hikari.HikariDataSource
        driver-class-name:com.mysql.cj.jdbc.Driver
        jdbc-url:jdbc:mysql://localhost:3306/db1?useSSL=false&serverTimezone=UTC
        username:root
        password:root
    rules:
      sharding:
        tables:
          t_product:
            actual-data-nodes:ds$->{0..1}.t_product_$->{0..1}
            table-strategy:
              standard:
                sharding-column:product_id
                sharding-algorithm-name:t_product_inline
            key-generate-strategy:
              column:product_id
              key-generator-name:snowflake
          t_order:
            actual-data-nodes:ds$->{0..1}.t_order_$->{0..1}
            table-strategy:
              standard:
                sharding-column:order_id
                sharding-algorithm-name:t_order_inline
            key-generate-strategy:
              column:order_id
              key-generator-name:snowflake
        binding-tables:
          -t_product,t_order
        sharding-algorithms:
          t_product_inline:
            type:INLINE
            props:
              algorithm-expression:t_product_$->{product_id%2}
          t_order_inline:
            type:INLINE
            props:
              algorithm-expression:t_order_$->{order_id%2}
        key-generators:
          snowflake:
            type:SNOWFLAKE
    props:
      sql-show:true

Product

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Entity(name = "t_product")
publicclass Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long productId;
    private String productName;
    private Integer stock;
}

Order

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Entity(name = "t_order")
publicclass Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderId;
    private Long productId;
    private Integer quantity;
}

Repository

package com.example.demo.repository;

import com.example.demo.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long> {
}

OrderRepository

package com.example.demo.repository;

import com.example.demo.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long> {
}

Service

package com.example.demo.service;

import com.example.demo.entity.Product;
import com.example.demo.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
publicclass ProductService {

    @Autowired
    private ProductRepository productRepository;

    public Product getProductById(Long productId) {
        return productRepository.findById(productId).orElseThrow(() -> new RuntimeException("Product not found"));
    }

    public void updateStock(Long productId, int quantity) {
        Product product = getProductById(productId);
        product.setStock(product.getStock() - quantity);
        productRepository.save(product);
    }
}

OrderService

package com.example.demo.service;

import com.example.demo.entity.Order;
import com.example.demo.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
publicclass OrderService {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private ProductService productService;

    @Transactional
    public void placeOrder(Long productId, int quantity) {
        // 檢查庫存
        if (!productService.getProductById(productId).getStock().equals(quantity)) {
            thrownew RuntimeException("Insufficient stock");
        }

        // 創建訂單
        Order order = new Order();
        order.setProductId(productId);
        order.setQuantity(quantity);
        orderRepository.save(order);

        // 扣減庫存
        productService.updateStock(productId, quantity);
    }
}

Controller

package com.example.demo.controller;

import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/products")
publicclass ProductController {

    @Autowired
    private ProductService productService;

    @GetMapping("/{productId}")
    public Product getProduct(@PathVariable Long productId) {
        return productService.getProductById(productId);
    }

    @PostMapping("/")
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product);
    }
}

OrderController

package com.example.demo.controller;

import com.example.demo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/orders")
publicclass OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/place-order")
    public String placeOrder(@RequestParam Long productId, @RequestParam int quantity) {
        try {
            orderService.placeOrder(productId, quantity);
            return"Order placed successfully";
        } catch (Exception e) {
            return"Failed to place order: " + e.getMessage();
        }
    }
}

Application

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

測試

curl -X POST http://localhost:8080/orders/place-order \
     -d "productId=1&quantity=5"

Respons

Order placed successfully


責任編輯:武曉燕 來源: Java知識日歷
相關推薦

2022-06-27 08:21:05

Seata分布式事務微服務

2023-12-26 08:59:52

分布式場景事務機制

2024-09-10 10:42:27

2020-09-23 22:36:27

分布式架構系統

2022-06-21 08:27:22

Seata分布式事務

2021-02-01 09:35:53

關系型數據庫模型

2025-03-11 08:36:52

高并發場景性能

2022-01-10 11:58:51

SpringBootPulsar分布式

2017-12-12 14:51:15

分布式緩存設計

2021-08-26 08:24:33

高并發秒殺系統

2023-01-13 07:39:07

2020-12-09 09:14:57

SpringCloudSeata 分布式

2020-09-03 06:33:35

高并發場景分布式鎖

2017-07-26 15:08:05

大數據分布式事務

2020-10-13 07:44:45

理解分布式

2024-11-27 00:20:32

2021-04-16 16:02:13

SpringBoot分布式最大努力通知

2024-01-05 07:28:50

分布式事務框架
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 粉色午夜视频 | 国产精品成人一区二区三区 | 北条麻妃99精品青青久久 | 视频一区二区在线观看 | 欧美视频免费在线 | 国产激情在线播放 | 在线看日韩 | 久久精品一区二区视频 | 成人久久| 91毛片在线看 | 黄色毛片在线看 | 国产精品久久久久久久久久不蜜臀 | 91久久精品日日躁夜夜躁欧美 | 国产一区在线免费观看视频 | 一区二区日本 | 亚洲国产成人精品女人久久久 | 久草中文在线 | 国产一区2区| 日韩中文字幕在线观看 | 人人九九精 | 国产精品亚洲一区 | 亚洲欧美综合 | 国产成人精品一区 | 欧美黄色一区 | 成年人视频在线免费观看 | 欧美成人免费在线 | 99国内精品久久久久久久 | 91精品国产91久久久久久密臀 | 操久久 | 国产二区三区 | 成人精品鲁一区一区二区 | 国产成人99久久亚洲综合精品 | 精品久久久久久久久久久久 | 欧美成人精品一区二区男人看 | 亚洲精品一区国语对白 | 97视频免费| 在线免费观看成人 | 人人玩人人干 | 黄网免费看 | 国产精品99久久久久久久vr | 一级在线|