pull/13/head
hfwangyl 2021-04-20 11:01:43 +08:00
parent 304ff3fb46
commit 368f3fd10f
18 changed files with 527 additions and 0 deletions

1
kernel-d-seata/README.md Normal file
View File

@ -0,0 +1 @@
分布式事务Seata模块

111
kernel-d-seata/db/db.sql Normal file
View File

@ -0,0 +1,111 @@
-- ----------------------------
-- 订单库
-- ----------------------------
DROP DATABASE IF EXISTS `order`;
CREATE DATABASE IF NOT EXISTS `order` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
USE `order`;
DROP TABLE IF EXISTS `order_info`;
CREATE TABLE `order_info` (
`order_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`product_id` bigint(20) NOT NULL COMMENT '商品ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`prod_price` double(8, 2) NOT NULL COMMENT '商品单价',
`prod_number` int(11) NOT NULL COMMENT '商品数量',
`total_amount` double(10, 2) NOT NULL COMMENT '总价',
`pay_status` int(11) NOT NULL COMMENT '支付状态:1待支付,2已支付,3支付失败,已取消',
`create_user` bigint(20) NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_user` bigint(20) NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `undo_log`;
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 COMMENT = 'seata事务记录';
-- ----------------------------
-- 仓储库
-- ----------------------------
DROP DATABASE IF EXISTS `storage`;
CREATE DATABASE IF NOT EXISTS `storage` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
USE `storage`;
DROP TABLE IF EXISTS `product_info`;
CREATE TABLE `product_info` (
`prod_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`prod_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品名称',
`inventory` int(11) NOT NULL COMMENT '库存数量',
`prod_price` double(8, 2) NOT NULL COMMENT '商品单价',
`prod_status` int(11) NOT NULL COMMENT '上架状态:1上架,2下架',
`create_user` bigint(20) NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_user` bigint(20) NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`prod_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品表' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `undo_log`;
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 COMMENT = 'seata事务记录';
-- ----------------------------
-- 用户库
-- ----------------------------
DROP DATABASE IF EXISTS `member`;
CREATE DATABASE IF NOT EXISTS `member` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci;
USE `member`;
DROP TABLE IF EXISTS `member_wallet`;
CREATE TABLE `member_wallet` (
`member_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '会员ID',
`member_balance` double(8, 2) DEFAULT '0.00' COMMENT '会员余额',
`member_integral` double(8, 2) DEFAULT '0.00' COMMENT '会员积分',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`update_user` bigint(20) NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`member_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户钱包' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `undo_log`;
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 COMMENT = 'seata事务记录';

Binary file not shown.

33
kernel-d-seata/pom.xml Normal file
View File

@ -0,0 +1,33 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>roses-kernel</artifactId>
<version>7.0.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kernel-d-seata</artifactId>
<packaging>pom</packaging>
<modules>
<module>seata-demo-wallet-api</module>
<module>seata-demo-storage-api</module>
<module>seata-demo-order</module>
</modules>
<dependencies>
<!-- 开发规则 -->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-a-rule</artifactId>
<version>7.0.2</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,41 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-seata</artifactId>
<version>7.0.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-demo-order</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>seata-demo-storage-api</artifactId>
<version>7.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>seata-demo-wallet-api</artifactId>
<version>7.0.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.3.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,13 @@
package cn.stylefeng.roses.kernel.seata.order.consumer;
import cn.stylefeng.roses.kernel.seata.api.StorageApi;
import org.springframework.cloud.openfeign.FeignClient;
/**
* api
* @author wangyl
* @Date 2021-04-10 9:25:13
*/
@FeignClient(name = "seata-demo-storage")
public interface StorageConsumer extends StorageApi {
}

View File

@ -0,0 +1,13 @@
package cn.stylefeng.roses.kernel.seata.order.consumer;
import cn.stylefeng.roses.kernel.seata.wallet.api.WalletApi;
import org.springframework.cloud.openfeign.FeignClient;
/**
* api
* @author wangyl
* @Date 2021-04-10 9:25:13
*/
@FeignClient(name = "seata-demo-wallet")
public interface WalletConsumer extends WalletApi {
}

View File

@ -0,0 +1,26 @@
package cn.stylefeng.roses.kernel.seata.order.controller;
import cn.stylefeng.roses.kernel.seata.order.entity.Order;
import cn.stylefeng.roses.kernel.seata.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
/**
*
* @author wangyl
* @Date 2021-04-10 9:25:13
*/
public class OrderController {
@Autowired
OrderService orderService;
/**
*
*/
@GetMapping("/create")
Order create(String userId, String commodityCode, int orderCount){
return orderService.create(userId,commodityCode,orderCount);
}
}

View File

@ -0,0 +1,116 @@
package cn.stylefeng.roses.kernel.seata.order.entity;
import java.io.Serializable;
import java.util.Date;
public class Order implements Serializable {
private Long orderId;
private Long productId;
private Long userId;
private Integer prodPrice;
private Integer prodNumber;
private Integer totalAmount;
private Integer payStatus;
private Long createUser;
private Date createTime;
private Long updateUser;
private Date updateTime;
private String remark;
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Integer getProdPrice() {
return prodPrice;
}
public void setProdPrice(Integer prodPrice) {
this.prodPrice = prodPrice;
}
public Integer getProdNumber() {
return prodNumber;
}
public void setProdNumber(Integer prodNumber) {
this.prodNumber = prodNumber;
}
public Integer getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(Integer totalAmount) {
this.totalAmount = totalAmount;
}
public Integer getPayStatus() {
return payStatus;
}
public void setPayStatus(Integer payStatus) {
this.payStatus = payStatus;
}
public Long getCreateUser() {
return createUser;
}
public void setCreateUser(Long createUser) {
this.createUser = createUser;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Long getUpdateUser() {
return updateUser;
}
public void setUpdateUser(Long updateUser) {
this.updateUser = updateUser;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
}

View File

@ -0,0 +1,16 @@
package cn.stylefeng.roses.kernel.seata.order.mapper;
import cn.stylefeng.roses.kernel.seata.order.entity.Order;
/**
*
*
* @author wangyl
*/
public interface OrderMapper {
void insertOrder(Order order);
Order selectById(Long orderId);
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.stylefeng.roses.kernel.seata.order.mapper.OrderMapper">
<insert id="insertOrder" parameterType="cn.stylefeng.roses.kernel.seata.order.entity.Order">
insert into order(
<if test="productId != null and productId != ''">product_id,</if>
<if test="userId != null and userId != ''">user_id,</if>
<if test="prodPrice != null and prodPrice != ''">prod_price,</if>
<if test="prodNumber != null and prodNumber != ''">prod_number,</if>
<if test="totalAmount != null and totalAmount != ''">total_amount,</if>
<if test="payStatus != null and payStatus != ''">pay_status,</if>
<if test="createUser != null and createUser != ''">create_user,</if>
<if test="createTime != null and createTime != ''">create_time</if>
<if test="updateUser != null and updateUser != ''">update_user,</if>
<if test="updateTime != null and updateTime != ''">update_time,</if>
<if test="remark != null and remark != ''">remark,</if>
)values(
<if test="productId != null and productId != ''">#{productId},</if>
<if test="userId != null and userId != ''">#{userId},</if>
<if test="prodPrice != null and prodPrice != ''">#{prodPrice},</if>
<if test="prodNumber != null and prodNumber != ''">#{prodNumber},</if>
<if test="totalAmount != null and totalAmount != ''">#{totalAmount},</if>
<if test="payStatus != null and payStatus != ''">#{payStatus},</if>
<if test="createUser != null and createUser != ''">#{createUser},</if>
<if test="createTime != null and createTime != ''">#{createTime}</if>
<if test="updateUser != null and updateUser != ''">#{updateUser},</if>
<if test="updateTime != null and updateTime != ''">#{updateTime},</if>
<if test="remark != null and remark != ''">#{remark},</if>
)
</insert>
<select id="selectById" resultType="cn.stylefeng.roses.kernel.seata.order.entity.Order">
select * from order
where order_id = #{orderId}
</select>
</mapper>

View File

@ -0,0 +1,9 @@
package cn.stylefeng.roses.kernel.seata.order.service;
import cn.stylefeng.roses.kernel.seata.order.entity.Order;
public interface OrderService {
Order create(String userId, String commodityCode, int orderCount);
}

View File

@ -0,0 +1,41 @@
package cn.stylefeng.roses.kernel.seata.order.service.impl;
import cn.stylefeng.roses.kernel.seata.order.consumer.StorageConsumer;
import cn.stylefeng.roses.kernel.seata.order.consumer.WalletConsumer;
import cn.stylefeng.roses.kernel.seata.order.entity.Order;
import cn.stylefeng.roses.kernel.seata.order.mapper.OrderMapper;
import cn.stylefeng.roses.kernel.seata.order.service.OrderService;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private StorageConsumer storageConsumer;
@Autowired
private WalletConsumer walletConsumer;
@Autowired
private OrderMapper orderMapper;
/**
* 使@GlobalTransactional
* @param userId
* @param commodityCode
* @param orderCount
* @return
*/
@GlobalTransactional(rollbackFor = Exception.class)
@Override
public Order create(String userId, String commodityCode, int orderCount) {
Order order = new Order();
//保存订单
orderMapper.insertOrder(order);
//扣减商品库存
storageConsumer.deduct(commodityCode,orderCount);
//扣用户钱
walletConsumer.debit(userId,order.getTotalAmount());
return order;
}
}

View File

@ -0,0 +1,17 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-seata</artifactId>
<version>7.0.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-demo-storage-api</artifactId>
<packaging>jar</packaging>
</project>

View File

@ -0,0 +1,16 @@
package cn.stylefeng.roses.kernel.seata.api;
/**
* api
*
* @author wangyl
* @date 2021-04-11 9:52:31
*/
public interface StorageApi {
/**
*
*/
void deduct(String commodityCode, int count);
}

View File

@ -0,0 +1,17 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-seata</artifactId>
<version>7.0.2</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>seata-demo-wallet-api</artifactId>
<packaging>jar</packaging>
</project>

View File

@ -0,0 +1,16 @@
package cn.stylefeng.roses.kernel.seata.wallet.api;
/**
* api
*
* @author wangyl
* @date 2021-04-10 8:56:48
*/
public interface WalletApi {
/**
*
*/
void debit(String userId, int money);
}

View File

@ -94,6 +94,9 @@
<!--系统管理基础业务-->
<module>kernel-s-system</module>
<!-- 分布式事务seata -->
<module>kernel-d-seata</module>
</modules>
<properties>