SpringCloud-整体学习(一)SpringCloud简介+版本选择
SpringCloud-整体学习(二)项目初始构建-加公共部分提取
SpringCloud-整体学习(三)Eureka、zookeeper、Consul(注册中心)
SpringCloud-整体学习(四)Ribbon(负载均衡+手写轮询算法)
SpringCloud-整体学习(五)OpenFeign(服务调用)
SpringCloud-整体学习(六)Hystrix(服务降级)
SpringCloud-整体学习(七)GateWay(服务网关)
SpringCloud-整体学习(八)Config、Bus、Stream(服务配置和消息交互)
SpringCloud-整体学习(九)Sleuth(分布式请求链路追踪)
SpringCloud-整体学习(十)SpringCloudAlibaba(注册中心+配置中心)
SpringCloud-整体学习(十一) Sentinel(服务降级)
SpringCloud-整体学习(十二) Seata(分布式事务)
git :
https://github.com/lucine-maker/cloud2020
gitee:
https://gitee.com/lucine_li_tao/springcloud
分布式事务问题由来
Seata - 文档(可以稍微了解下)
http://seata.io/zh-cn/docs/overview/what-is-seata.html
我的理解(如果不对请纠正我):
在一个update语句执行之前他会记录之前的状态(比如一个字段原本是2,你想把他改成1,他会把2先记录下来以json的格式),json中有用于回滚的定位信息其中两个是比较特殊的branchId、xid。
如:
Seata术语
http://seata.io/zh-cn/docs/overview/terminology.html
1+3
1全局唯一的事务id Transaction ID XID
3:
处理过程:
Seata-Server安装
我下载的是1.0的
file.conf
mysql 版本是8的:
需要修改class 5 的不需要
8的并且在lib中中加入mysql连接8的.jar (记得删除掉5版本的)
Seata业务数据库准备
目前创建3个moudle
一个订单
一个库存
一个账户
执行操作:
下订单->减库存->扣账户余额->修改订单状态
CREATE DATABASE seata_account;
USE seata_account;
CREATE TABLE t_account(
id BIGINT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
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 '剩余可用额度'
)ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8;
INSERT INTO t_account(id, user_id, total, used, residue) VALUES(1,1,1000,0,1000);
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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE 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 '剩余库存'
)ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8;
INSERT INTO t_storage(id, product_id, total, used, residue) VALUES(1,1,100,0,100);
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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE 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已完结'
)ENGINE=InnoDB AUTO_INCREMENT=7 CHARSET=utf8;
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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Seata的相关Module配置搭建
相关代码我会放在github和gitee
坑:版本问题
https://blog.csdn.net/qq_34775355/article/details/108587949
Seata之@GlobalTransactional验证
只需要加一个@GlobalTransaction 方法就好了。
Seata之原理简介
分为2个阶段
1、业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源
2、提交异步化,非常快速地完成。
回滚通过一阶段的回滚日志进行反向补偿。
具体的文档蛮清楚的。
大厂面试第三季预告片之雪花算法(上)
生成一个订单的订单号
一、硬性要求:
1、全局唯一 :唯一标识问题
2、趋势递增 :mysql存储引擎InnoDB引擎多使用Btree,有序的话有利于存储。
3、单调递增 :
4、信息安全 :
5、包含时间戳 :方便后续排除问题,定位问题时间
二、性能要求
1、高可用:当请求发起后,服务要保证99.999%情况下,生成一个全局唯一ID
2、低延迟:ms级别
3、高QPS:比如一ms生成10w个id
基本上用的:
UUID:
缺点:
缺点不自增、太长、入库性能差,基本只满足了唯一
数据库自增ID:
replace into 跟 insert 功能类似
不同点在于:
replace into 首先尝试插入数据到表中,
- 如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据。
- 否则,直接插入新数据。
缺点:分库分表后处理复杂,高可用不满足
基于redis生成全局ID策略:
缺点:部署麻烦,功能都满足
大厂面试第三季预告片之雪花算法(下)
snowflake:
Twitter的分布式自增ID算法snow