TCC distributed transaction component based on hyperf framework / 基于Hyperf框架的TCC分布式事务组件
基于 Hyperf 框架的分布式事务 TCC 组件
AOP
并且代码 可读性较差
用的不太顺就自己搞了一个测试
和 PR
在使用 tcc 前先确保已经安装 Redis, Nsq
composer require yogcloud/hyperf-tcc
发布资源
php bin/hyperf.php vendor:publish yogcloud/hyperf-tcc
执行迁移
php bin/hyperf.php migrate
use YogCloud\TccTransaction\Example\Test;
/**
* @GetMapping(path="nsq")
*/
public function nsq(RequestInterface $req, ResponseInterface $res)
{
$goodsId = $req->input('goods_id', 1);
$couponId = $req->input('coupon_id', 0);
$result = (new Test())->handle($goodsId,$couponId);
return $res->json([
'code' => 0,
'data' => $result,
]);
}
curl http://localhost:9501/index/nsq?goods_id=1&coupon_id=0
{"code":0,"data":{"order":{"order_sn":255041892524236800,"body":"购买桃子","total_fee":"200.00","goods_id":1,"id":2483},"goods":{"id":1,"price":"200.00","name":"桃子","num":9994,"lock":0,"sale":6},"coupon":null}}
RateLimit
组件)1. nsqlookupd
2. nsqd --lookupd-tcp-address=127.0.0.1:4160
config/autoload/nsq.php 使用默认配置端口即可
TccOption
Tcc
Tcc->rely(...)
NSQ消息订阅
Database
"hyperf/nsq": "^2.1"
"hyperf/redis": "~2.1.0"
"hyperf/database": "~2.1.0"
"hyperf/snowflake": "^2.1"
"hyperf/logger": "~2.1.0"
"hyperf/db-connection": "~2.1.0"
Tcc
事务创建
TccOption
事务操作
try, confirm, cancel
方法商品库存锁定
, 商品库存扣除
等YogCloud\TccTransaction\Example\Tcc
下能看到很多演示写法复杂的参数
放到该类中去例如对象等, 因为它会作为一个 序列化的类
存放到 redis
中参数过多
, 或者 属性
中 对象过多
会造成 存储负担
TccOption
操作类中写业务逻辑, 它应当作为一个调用服务的封装TccState
事务状态
Coordinator/TccCoordinator
事务协调者 NSQ消费者
需要加入到消费进程
NSQ消费者进程绑定 @Consumer 注解
Example
中有实现Example\Tcc\*
事务操作项Example\Service\*
微服务实现类Example\Test
模拟下单接口Example\database.sql
演示案例数据库脚本, 测试前先导入use YogCloud\TccTransaction\Tcc;
use YogCloud\TccTransaction\Example\Tcc\GoodsLockTcc;
use YogCloud\TccTransaction\Example\Tcc\CouponLockTcc;
use YogCloud\TccTransaction\Example\Tcc\OrderTcc;
use YogCloud\TccTransaction\Example\Tcc\GoodsSubTcc;
use YogCloud\TccTransaction\Example\Tcc\CouponSubTcc;
use YogCloud\TccTransaction\Example\Tcc\OrderMessageTcc;
use YogCloud\TccTransaction\Example\Tcc\OrderStatisticsTcc;
$goodsId = 1;
$couponId = 0;
$tcc = new Tcc;
$tcc
->tcc(1, new GoodsLockTcc($goodsId)) // 商品库存锁定
->tcc(2, new CouponLockTcc($couponId)) // 优惠券锁定
->tcc(3, new OrderTcc) // 创建订单
->tcc(4, new GoodsSubTcc) // 扣减库存
->tcc(5, new CouponSubTcc) // 占用优惠券
->tcc(6, new OrderMessageTcc) // 创建订单消息
->tcc(7, new OrderStatisticsTcc) // 订单统计
->rely([ // 配置执行流程
// 外层步骤是逐步执行的
// [...] 内层步骤是同步执行的
[1, 2], // 1,2 锁定库存, 锁定优惠券
[3], // 3 创建订单
[4, 5, 6, 7], // 4,5,6,7 扣减库存, 占用优惠券, 订单消息, 订单统计
])->begin(); // 开启事务
TccOption
都必须实现 try, confirm, cancel
方法confirm
允许空操作PHP
方便辨认h6play