装修队做网站,企业怎么建设网站首页,企业推广宣传文案,公司做网站还是做app业务说明#xff1a;这里我们创建三个服务#xff0c;一个订单服务#xff0c;一个库存服务#xff0c;一个账户服务。当用户下单时#xff0c;会在订单服务中创建一个订单#xff0c;然后通过远程调用库存服务来扣减下单商品的库存#xff1b;再通过远程调用账户服务来… 业务说明这里我们创建三个服务一个订单服务一个库存服务一个账户服务。当用户下单时会在订单服务中创建一个订单然后通过远程调用库存服务来扣减下单商品的库存再通过远程调用账户服务来扣减用户账户里面的余额最后在订单服务中修改订单状态为已完成。该操作跨越三个数据库有两次远程调用很明显会有分布式事务问题 6.1.数据库表准备
a.建三个数据库
CREATE DATABASE seata_order;
CREATE DATABASE seata_storage;
CREATE DATABASE seata_account;b.undo_log回滚日志表
1.按照上述的3个数据库分别对应的undo_log回滚日志表2.seata官网3.undo_log建表SQL如下AT模式专用的其他模式都不需要
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS undo_log
(branch_id BIGINT NOT NULL COMMENT branch transaction id,xid VARCHAR(128) NOT NULL COMMENT global transaction id,context VARCHAR(128) NOT NULL COMMENT undo_log context,such as serialization,rollback_info LONGBLOB NOT NULL COMMENT rollback info,log_status INT(11) NOT NULL COMMENT 0:normal status,1:defense status,log_created DATETIME(6) NOT NULL COMMENT create datetime,log_modified DATETIME(6) NOT NULL COMMENT modify datetime,UNIQUE KEY ux_undo_log (xid, branch_id)
) ENGINE InnoDB AUTO_INCREMENT 1 DEFAULT CHARSET utf8mb4 COMMENT AT transaction mode undo table;
ALTER TABLE undo_log ADD INDEX ix_log_created (log_created);c.按照3个库分别对应业务表
CREATE TABLE t_order(
id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,
product_id BIGINT(11)DEFAULT NULL COMMENT 产品id,
count INT(11) DEFAULT NULL COMMENT 数量,
money DECIMAL(11,0) DEFAULT NULL COMMENT 金额,
status INT(1) DEFAULT NULL COMMENT 订单状态: 0:创建中; 1:已完结
)ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;
SELECT * FROM t_order;CREATE TABLE t_account(
id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT id,
user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,
total DECIMAL(10,0) DEFAULT NULL COMMENT 总额度,
used DECIMAL(10,0) DEFAULT NULL COMMENT 已用账户余额,
residue DECIMAL(10,0) DEFAULT 0 COMMENT 剩余可用额度
)ENGINEINNODB AUTO_INCREMENT2 DEFAULT CHARSETutf8;
INSERT INTO t_account(id,user_id,total,used,residue)VALUES(1,1,1000,0,1000);
SELECT * FROM t_account;CREATE TABLE t_storage(
id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
product_id BIGINT(11) DEFAULT NULL COMMENT 产品id,
total INT(11) DEFAULT NULL COMMENT 总库存,
used INT(11) DEFAULT NULL COMMENT 已用库存,
residue INT(11) DEFAULT NULL COMMENT 剩余库存
)ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;INSERT INTO t_storage(id,product_id,total,used,residue)VALUES(1,1,100,0,100);SELECT * FROM t_storage;d.最终的效果 库表图 所有的SQL 1.建seata_order库 建t_order表 undo_log表
#orderCREATE DATABASE seata_order;USE seata_order;CREATE TABLE t_order(id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,product_id BIGINT(11)DEFAULT NULL COMMENT 产品id,count INT(11) DEFAULT NULL COMMENT 数量,money DECIMAL(11,0) DEFAULT NULL COMMENT 金额,status INT(1) DEFAULT NULL COMMENT 订单状态: 0:创建中; 1:已完结)ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;SELECT * FROM t_order;-- for AT mode you must to init this sql for you business database. the seata server not need it.CREATE TABLE IF NOT EXISTS undo_log(branch_id BIGINT NOT NULL COMMENT branch transaction id,xid VARCHAR(128) NOT NULL COMMENT global transaction id,context VARCHAR(128) NOT NULL COMMENT undo_log context,such as serialization,rollback_info LONGBLOB NOT NULL COMMENT rollback info,log_status INT(11) NOT NULL COMMENT 0:normal status,1:defense status,log_created DATETIME(6) NOT NULL COMMENT create datetime,log_modified DATETIME(6) NOT NULL COMMENT modify datetime,UNIQUE KEY ux_undo_log (xid, branch_id)) ENGINE InnoDB AUTO_INCREMENT 1 DEFAULT CHARSET utf8mb4 COMMENT AT transaction mode undo table;ALTER TABLE undo_log ADD INDEX ix_log_created (log_created);2.建seata_storage库 建t_storage表 undo_log表
#storageCREATE DATABASE seata_storage;USE seata_storage;CREATE TABLE t_storage(id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,product_id BIGINT(11) DEFAULT NULL COMMENT 产品id,total INT(11) DEFAULT NULL COMMENT 总库存,used INT(11) DEFAULT NULL COMMENT 已用库存,residue INT(11) DEFAULT NULL COMMENT 剩余库存)ENGINEINNODB AUTO_INCREMENT1 DEFAULT CHARSETutf8;INSERT INTO t_storage(id,product_id,total,used,residue)VALUES(1,1,100,0,100);SELECT * FROM t_storage;-- for AT mode you must to init this sql for you business database. the seata server not need it.CREATE TABLE IF NOT EXISTS undo_log(branch_id BIGINT NOT NULL COMMENT branch transaction id,xid VARCHAR(128) NOT NULL COMMENT global transaction id,context VARCHAR(128) NOT NULL COMMENT undo_log context,such as serialization,rollback_info LONGBLOB NOT NULL COMMENT rollback info,log_status INT(11) NOT NULL COMMENT 0:normal status,1:defense status,log_created DATETIME(6) NOT NULL COMMENT create datetime,log_modified DATETIME(6) NOT NULL COMMENT modify datetime,UNIQUE KEY ux_undo_log (xid, branch_id)) ENGINE InnoDB AUTO_INCREMENT 1 DEFAULT CHARSET utf8mb4 COMMENT AT transaction mode undo table;ALTER TABLE undo_log ADD INDEX ix_log_created (log_created);3.建seata_account库 建t_account表 undo_log表
#accountcreate database seata_account;use seata_account;CREATE TABLE t_account(id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT id,user_id BIGINT(11) DEFAULT NULL COMMENT 用户id,total DECIMAL(10,0) DEFAULT NULL COMMENT 总额度,used DECIMAL(10,0) DEFAULT NULL COMMENT 已用余额,residue DECIMAL(10,0) DEFAULT 0 COMMENT 剩余可用额度)ENGINEINNODB AUTO_INCREMENT2 DEFAULT CHARSETutf8;INSERT INTO t_account(id,user_id,total,used,residue)VALUES(1,1,1000,0,1000);SELECT * FROM t_account;-- for AT mode you must to init this sql for you business database. the seata server not need it.CREATE TABLE IF NOT EXISTS undo_log(branch_id BIGINT NOT NULL COMMENT branch transaction id,xid VARCHAR(128) NOT NULL COMMENT global transaction id,context VARCHAR(128) NOT NULL COMMENT undo_log context,such as serialization,rollback_info LONGBLOB NOT NULL COMMENT rollback info,log_status INT(11) NOT NULL COMMENT 0:normal status,1:defense status,log_created DATETIME(6) NOT NULL COMMENT create datetime,log_modified DATETIME(6) NOT NULL COMMENT modify datetime,UNIQUE KEY ux_undo_log (xid, branch_id)) ENGINE InnoDB AUTO_INCREMENT 1 DEFAULT CHARSET utf8mb4 COMMENT AT transaction mode undo table;ALTER TABLE undo_log ADD INDEX ix_log_created (log_created);6.2.微服务编码和落地实现 整个业务流程下订单 - 减库存 -扣余额 - 改订单状态 a.MyBatis一键生成 config.properties #t_pay表包名
package.namecom.atguigu.cloud# mysql8.0
jdbc.driverClass com.mysql.cj.jdbc.Driver
jdbc.url jdbc:mysql://localhost:3306/db2024?characterEncodingutf8useSSLfalseserverTimezoneGMT%2B8rewriteBatchedStatementstrueallowPublicKeyRetrievaltrue
jdbc.user root
jdbc.password 123456# seata_order
#jdbc.driverClass com.mysql.cj.jdbc.Driver
#jdbc.url jdbc:mysql://localhost:3306/seata_order?characterEncodingutf8useSSLfalseserverTimezoneGMT%2B8rewriteBatchedStatementstrueallowPublicKeyRetrievaltrue
#jdbc.user root
#jdbc.password 123456# seata_storage
#jdbc.driverClass com.mysql.cj.jdbc.Driver
#jdbc.url jdbc:mysql://localhost:3306/seata_storage?characterEncodingutf8useSSLfalseserverTimezoneGMT%2B8rewriteBatchedStatementstrueallowPublicKeyRetrievaltrue
#jdbc.user root
#jdbc.password 123456# seata_account
#jdbc.driverClass com.mysql.cj.jdbc.Driver
#jdbc.url jdbc:mysql://localhost:3306/seata_account?characterEncodingutf8useSSLfalseserverTimezoneGMT%2B8rewriteBatchedStatementstrueallowPublicKeyRetrievaltrue
#jdbc.user root
#jdbc.password 123456generatorConfig.xml ?xml version1.0 encodingUTF-8?
!DOCTYPE generatorConfigurationPUBLIC -//mybatis.org//DTD MyBatis Generator Configuration 1.0//ENhttp://mybatis.org/dtd/mybatis-generator-config_1_0.dtdgeneratorConfigurationproperties resourceconfig.properties/context idMysql targetRuntimeMyBatis3Simple defaultModelTypeflatproperty namebeginningDelimiter value/property nameendingDelimiter value/plugin typetk.mybatis.mapper.generator.MapperPluginproperty namemappers valuetk.mybatis.mapper.common.Mapper/property namecaseSensitive valuetrue//pluginjdbcConnection driverClass${jdbc.driverClass}connectionURL${jdbc.url}userId${jdbc.user}password${jdbc.password}/jdbcConnectionjavaModelGenerator targetPackage${package.name}.entities targetProjectsrc/main/java/sqlMapGenerator targetPackage${package.name}.mapper targetProjectsrc/main/java/javaClientGenerator targetPackage${package.name}.mapper targetProjectsrc/main/java typeXMLMAPPER/table tableNamet_pay domainObjectNamePaygeneratedKey columnid sqlStatementJDBC//table!-- seata_order --!--table tableNamet_order domainObjectNameOrdergeneratedKey columnid sqlStatementJDBC//table--!--seata_storage--!--table tableNamet_storage domainObjectNameStoragegeneratedKey columnid sqlStatementJDBC//table--!--seata_account--!--table tableNamet_account domainObjectNameAccountgeneratedKey columnid sqlStatementJDBC//table--/context
/generatorConfigurationb.修改公共cloud-api-commons模块 新增库存和账户两个Feign服务接口 1.StorageFeignApi.java
package com.atguigu.cloud.apis;
import com.atguigu.cloud.resp.ResultData;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;/*** auther zzyy* create 2023-12-01 17:41*/
FeignClient(value seata-storage-service)
public interface StorageFeignApi
{/*** 扣减库存*/PostMapping(value /storage/decrease)ResultData decrease(RequestParam(productId) Long productId, RequestParam(count) Integer count);
}2.AccountFeignApi.java
package com.atguigu.cloud.apis;import com.atguigu.cloud.resp.ResultData;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;/*** auther zzyy* create 2023-12-01 17:42*/
FeignClient(value seata-account-service)
public interface AccountFeignApi
{//扣减账户余额PostMapping(/account/decrease)ResultData decrease(RequestParam(userId) Long userId, RequestParam(money) Long money);
}d.新建订单Order微服务
e.新建库存Storag微服务
c.新建账户Account微服务
6.3.测试
b.