当前位置: 首页 > news >正文

前几年做那些网站能致富百度精简版网页入口

前几年做那些网站能致富,百度精简版网页入口,wap网站如何做,公关公司组织架构图文章目录 1、分布式事务1.1 事务的ACID原则原子性一致性隔离性持久性 1.2 分布式事务的问题示例代码准备环境1. seata_demo数据库2. 启动nacos seata-demo父工程pom.xml order-servicepom.xmlapplication.ymlOrderApplicationOrderControllerOrderServiceImplAccountClientStor…

文章目录

  • 1、分布式事务
    • 1.1 事务的ACID原则
      • 原子性
      • 一致性
      • 隔离性
      • 持久性
    • 1.2 分布式事务的问题
      • 示例
      • 代码
        • 准备环境
          • 1. seata_demo数据库
          • 2. 启动nacos
        • seata-demo父工程
          • pom.xml
        • order-service
          • pom.xml
          • application.yml
          • OrderApplication
          • OrderController
          • OrderServiceImpl
          • AccountClient
          • StorageClient
        • account-service
          • pom.xml
          • application.yml
          • AccountApplication
          • AccountController
          • AccountServiceImpl
        • storage-service
          • pom.xml
          • application.yml
          • StorageApplication
          • StorageApplication
          • AccountServiceImpl
  • 2、理论基础
    • 2.1 CAP定理
    • 2.2 BASE理论
    • 2.3 分布式事务模型
  • 3、seata
    • Seata的架构

1、分布式事务

1.1 事务的ACID原则

原子性

事务中的所有操作,要么全部成功,要么全部失败

一致性

要保证数据库内部完整性约束、声明性约束

隔离性

对同一资源操作的事务不能同时发生

持久性

对数据库做的一切修改将永久保存,不管是否出现故障

1.2 分布式事务的问题

在单体架构中,往往只有1个服务,1个数据库。在这种情况下,基于数据库本身提供的特性,已经可以实现ACID了。但是,现在需要面对微服务架构,在微服务架构中,每个微服务都有可能有自己的数据库,这个时候就不能只依靠数据库本身提供的特性了来保证ACID了。

示例

我们来看下面这个示例

微服务下单业务,在下单时会调用订单服务,创建订单并写入数据库。然后订单服务调用账户服务和库存服务:

  • 账户服务负责扣减用户余额
  • 库存服务负责扣减商品库存

在这里插入图片描述

首先,我们请求:http://localhost:8082/order?userId=user202103032042012&commodityCode=100202003032041&count=2&money=200,因为目前库存是够的,所以正常创建订单、扣减余额,扣减商品库存。

然后我们请求:http://localhost:8082/order?userId=user202103032042012&commodityCode=100202003032041&count=10&money=200,显然,此时库存是不够的,库存服务的调用抛出了异常,但是我们发现余额仍然被扣除了,订单没有生成。这样就出现了数据库不一致的情况。

在以上的过程中,我们发现如下的问题:

  • 每1个服务都是独立的,当某个服务抛出了异常,其它服务并不能感知到;

  • 每1个服务都是独立的,所以它们的事务也都是独立的,其中业务处理成功的服务都各自把自己的事务提交了,因此撤销不了;

因此,没有达成事务状态的一致。

代码

准备环境
1. seata_demo数据库

seata_demo的数据库脚本,用于创建account_tbl(账户表)、order_tbl(订单表)、storage_tbl(库存表),并初始化数据。

/*Navicat Premium Data TransferSource Server         : localSource Server Type    : MySQLSource Server Version : 50622Source Host           : localhost:3306Source Schema         : seata_demoTarget Server Type    : MySQLTarget Server Version : 50622File Encoding         : 65001Date: 24/06/2021 19:55:35
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for account_tbl
-- ----------------------------
DROP TABLE IF EXISTS `account_tbl`;
CREATE TABLE `account_tbl`  (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`money` int(11) UNSIGNED NULL DEFAULT 0,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;-- ----------------------------
-- Records of account_tbl
-- ----------------------------
INSERT INTO `account_tbl` VALUES (1, 'user202103032042012', 1000);-- ----------------------------
-- Table structure for order_tbl
-- ----------------------------
DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl`  (`id` int(11) NOT NULL AUTO_INCREMENT,`user_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`commodity_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`count` int(11) NULL DEFAULT 0,`money` int(11) NULL DEFAULT 0,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;-- ----------------------------
-- Records of order_tbl
-- ------------------------------ ----------------------------
-- Table structure for storage_tbl
-- ----------------------------
DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl`  (`id` int(11) NOT NULL AUTO_INCREMENT,`commodity_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`count` int(11) UNSIGNED NULL DEFAULT 0,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `commodity_code`(`commodity_code`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPACT;-- ----------------------------
-- Records of storage_tbl
-- ----------------------------
INSERT INTO `storage_tbl` VALUES (1, '100202003032041', 10);SET FOREIGN_KEY_CHECKS = 1;

账户表

在这里插入图片描述

订单表

在这里插入图片描述

库存表

在这里插入图片描述

2. 启动nacos

下载nacos-server-xxx.zip包,并创建nacos需要的表,然后修改配置,单机启动即可

seata-demo父工程
pom.xml
<?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"><modelVersion>4.0.0</modelVersion><groupId>cn.itcast.demo</groupId><artifactId>seata-demo</artifactId><version>1.0-SNAPSHOT</version><modules><module>storage-service</module><module>account-service</module><module>order-service</module></modules><packaging>pom</packaging><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Hoxton.SR8</spring-cloud.version><mybatis.plus.version>3.3.0</mybatis.plus.version><mysql.version>5.1.47</mysql.version><alibaba.version>2.2.5.RELEASE</alibaba.version><seata.version>1.4.2</seata.version></properties><dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!-- springCloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis.plus.version}</version></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.4</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
</project>
order-service
pom.xml
<?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><artifactId>seata-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>order-service</artifactId><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
application.yml
server:port: 8082
spring:application:name: order-servicedatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///seata_demo?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=falseusername: rootpassword: rootcloud:nacos:server-addr: localhost:8848
mybatis-plus:global-config:db-config:insert-strategy: not_nullupdate-strategy: not_nullid-type: auto
logging:level:org.springframework.cloud.alibaba.seata.web: debugcn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
OrderApplication
@MapperScan("cn.itcast.order.mapper")
@EnableFeignClients
@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}
OrderController

创建订单

@RestController
@RequestMapping("order")
public class OrderController {private final OrderService orderService;public OrderController(OrderService orderService) {this.orderService = orderService;}@PostMappingpublic ResponseEntity<Long> createOrder(Order order){Long orderId = orderService.create(order);return ResponseEntity.status(HttpStatus.CREATED).body(orderId);}
}
OrderServiceImpl
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {private final AccountClient accountClient;private final StorageClient storageClient;private final OrderMapper orderMapper;public OrderServiceImpl(AccountClient accountClient, StorageClient storageClient, OrderMapper orderMapper) {this.accountClient = accountClient;this.storageClient = storageClient;this.orderMapper = orderMapper;}@Override@Transactionalpublic Long create(Order order) {// 创建订单orderMapper.insert(order);try {// 扣用户余额accountClient.deduct(order.getUserId(), order.getMoney());// 扣库存storageClient.deduct(order.getCommodityCode(), order.getCount());} catch (FeignException e) {log.error("下单失败,原因:{}", e.contentUTF8(), e);throw new RuntimeException(e.contentUTF8(), e);}return order.getId();}
}
AccountClient
@FeignClient("account-service")
public interface AccountClient {@PutMapping("/account/{userId}/{money}")void deduct(@PathVariable("userId") String userId, @PathVariable("money") Integer money);
}
StorageClient
@FeignClient("storage-service")
public interface StorageClient {@PutMapping("/storage/{code}/{count}")void deduct(@PathVariable("code") String code, @PathVariable("count") Integer count);
}
account-service
pom.xml
<?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><artifactId>seata-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>account-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
application.yml
server:port: 8083
spring:application:name: account-servicedatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///seata_demo?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=falseusername: rootpassword: rootcloud:nacos:server-addr: localhost:8848
mybatis-plus:global-config:db-config:insert-strategy: not_nullupdate-strategy: not_nullid-type: auto
logging:level:org.springframework.cloud.alibaba.seata.web: debugcn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
AccountApplication
@MapperScan("cn.itcast.account.mapper")
@SpringBootApplication
public class AccountApplication {public static void main(String[] args) {SpringApplication.run(AccountApplication.class, args);}
}
AccountController
@RestController
@RequestMapping("account")
public class AccountController {@Autowiredprivate AccountService accountService;@PutMapping("/{userId}/{money}")public ResponseEntity<Void> deduct(@PathVariable("userId") String userId, @PathVariable("money") Integer money){accountService.deduct(userId, money);return ResponseEntity.noContent().build();}
}
AccountServiceImpl
@Slf4j
@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountMapper accountMapper;@Override@Transactionalpublic void deduct(String userId, int money) {log.info("开始扣款");try {accountMapper.deduct(userId, money);} catch (Exception e) {throw new RuntimeException("扣款失败,可能是余额不足!", e);}log.info("扣款成功");}
}
storage-service
pom.xml
<?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><artifactId>seata-demo</artifactId><groupId>cn.itcast.demo</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>storage-service</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
application.yml
server:port: 8081
spring:application:name: storage-servicedatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///seata_demo?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&useSSL=falseusername: rootpassword: rootcloud:nacos:server-addr: localhost:8848
mybatis-plus:global-config:db-config:insert-strategy: not_nullupdate-strategy: not_nullid-type: auto
logging:level:org.springframework.cloud.alibaba.seata.web: debugcn.itcast: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
StorageApplication
@MapperScan("cn.itcast.storage.mapper")
@SpringBootApplication
public class StorageApplication {public static void main(String[] args) {SpringApplication.run(StorageApplication.class, args);}
}
StorageApplication
@MapperScan("cn.itcast.storage.mapper")
@SpringBootApplication
public class StorageApplication {public static void main(String[] args) {SpringApplication.run(StorageApplication.class, args);}
}
AccountServiceImpl
@Slf4j
@Service
public class StorageServiceImpl implements StorageService {@Autowiredprivate StorageMapper storageMapper;@Transactional@Overridepublic void deduct(String commodityCode, int count) {log.info("开始扣减库存");try {storageMapper.deduct(commodityCode, count);} catch (Exception e) {throw new RuntimeException("扣减库存失败,可能是库存不足!", e);}log.info("扣减库存成功");}
}

2、理论基础

2.1 CAP定理

1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标:

  • Consistency(一致性)

    • 用户访问分布式系统中的任意节点,得到的数据必须一致

      在这里插入图片描述

  • Availability(可用性)

    • 用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝

    在这里插入图片描述

  • Partition tolerance (分区容错性)

    • Partition(分区):因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接,形成独立分区。

    • Tolerance(容错):在集群出现分区时,整个系统也要持续对外提供服务(而一旦对外提供服务的话,那么由于形成了独立分区,它并未与其它节点进行数据同步,那么如果此时它提供给外界服务,就会达不到一致性的要求,如果它阻塞外界的请求,等待网络恢复数据同步完成,又会达不到可用性的要求)

      在这里插入图片描述

Eric Brewer 说,分布式系统无法同时满足这三个指标。这个结论就叫做 CAP 定理。

在这里插入图片描述

简述CAP定理内容?

  • 分布式系统节点通过网络连接,一定会出现分区问题(P)
  • 当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足

思考:elasticsearch集群是CP还是AP?

  • ES集群出现分区时,故障节点会被剔除集群,数据分片会重新分配到其它节点,保证数据一致。因此是低可用性,高一致性,属于CP

2.2 BASE理论

BASE理论是对CAP的一种解决思路,包含三个思想:

  • Basically Available (基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
  • Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。
  • Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。

而分布式事务最大的问题是各个子事务的一致性问题,因此可以借鉴CAP定理和BASE理论:

  • AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现最终一致
  • CP模式:各个子事务执行后互相等待,同时提交,同时回滚,达成强一致。但事务等待过程中,处于弱可用状态。

2.3 分布式事务模型

解决分布式事务,各个子系统之间必须能感知到彼此的事务状态,才能保证状态一致,因此需要一个事务协调者来协调每一个事务的参与者(子系统事务)。

这里的子系统事务,称为分支事务;有关联的各个分支事务在一起称为全局事务

在这里插入图片描述

简述BASE理论三个思想:

  • 基本可用
  • 软状态
  • 最终一致

解决分布式事务的思想和模型:

  • 全局事务:整个分布式事务
  • 分支事务:分布式事务中包含的每个子系统的事务
  • 最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据
  • 强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚

3、seata

Seata的架构

初识Seata

Seata是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。致力于提供高性能和简单易用的分布式事务服务,为用户打造一站式的分布式解决方案。

官网地址:http://seata.io/,其中的文档、播客中提供了大量的使用说明、源码分析。

在这里插入图片描述

Seata事务管理中有三个重要的角色

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

在这里插入图片描述

Seata提供了四种不同的分布式事务解决方案

  • XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入
  • TCC模式:最终一致的分阶段事务模式,有业务侵入
  • AT模式:最终一致的分阶段事务模式,无业务侵入,也是Seata的默认模式
  • SAGA模式:长事务模式,有业务侵入
http://www.khdw.cn/news/28048.html

相关文章:

  • 厚街镇做网站新网站如何快速收录
  • 做毕设的网站苏州网站优化公司
  • 做网站注意什么问题百度入口官网
  • 满屏网站做多大尺寸seo优化工具软件
  • 保定网站制作计划广告推广图片
  • 文化传播网站建设指数型基金
  • 加强网站建设和维护工作伊春seo
  • 北京市住房和城乡建设委员会官方网站的怎样在浏览器上找网站
  • 网站建设蓝图ppt微商怎么引流被别人加
  • 做订阅号要建立网站吗搜狗搜索引擎入口
  • 建瓯企业网站建设台州百度推广优化
  • 石家庄城市建设档案馆网站优化seo培训班
  • php网站开发 知乎站长工具网站推广
  • 赣州网站建设价格关键词优化的作用
  • 高手优化网站想要网站推广页
  • wordpress 管理员密码优化落实防控措施
  • 公众号做视频网站吗深圳广告公司排名
  • 吕子乔做网站吹的语录百度号码认证申诉平台
  • 装修公司经营范围武汉seo排名公司
  • 测评网站怎么做霸屏推广
  • 微信网站开发教程seo优化在线诊断
  • wordpress frp穿透北京度seo排名
  • 能看的网站软文营销文案
  • 中国东凤网站制作seo搜索优化公司
  • 电脑软件和网站怎么做网络策划方案
  • 济宁网站建设第一品牌企业培训课程价格
  • 网站前置审批证书软文广告营销
  • java做网站开发成本高网址大全2345
  • 公司要招个做网站的人灰色行业seo大神
  • 常见的网站开发语言产品软文范例大全