DTM 게시 0 2021-06-04 .1 버전, 빠르게 개발 중 |
|
위와 비교한 특성으로 볼 때 DTM은 여러 측면에서 큰 장점을 가지고 있습니다. 다중 언어 지원 및 다중 스토리지 엔진 지원을 고려한다면 의심할 여지 없이 DTM이 첫 번째 선택입니다.
Installation
Composer
composer require dtm/dtm-client
- 를 통해 dtm-client를 설치하는 것이 매우 편리합니다. 사용 시 DTM 서버 오
Configuration
구성 파일
Hyperf 프레임워크에서 사용하는 경우 컴포넌트 설치 후 다음 vendor:publish
를 사용하면 됩니다. > 구성 파일을 한 조각으로 게시하는 명령 ./config/autoload/dtm.php
vendor:publish
命令一件发布配置文件于 ./config/autoload/dtm.php
php bin/hyperf.php vendor:publish dtm/dtm-client
如果您是在非 Hyperf 框架中使用,可复制 ./vendor/dtm/dtm-client/publish/dtm.php
文件到对应的配置目录中。
use DtmClient\Constants\Protocol;
use DtmClient\Constants\DbType;
return [
// 客户端与 DTM Server 通讯的协议,支持 Protocol::HTTP 和 Protocol::GRPC 两种
'protocol' => Protocol::HTTP,
// DTM Server 的地址
'server' => '127.0.0.1',
// DTM Server 的端口
'port' => [
'http' => 36789,
'grpc' => 36790,
],
// 子事务屏障配置
'barrier' => [
// DB 模式下的子事务屏障配置
'db' => [
'type' => DbType::MySQL
],
// Redis 模式下的子事务屏障配置
'redis' => [
// 子事务屏障记录的超时时间
'expire_seconds' => 7 * 86400,
],
// 非 Hyperf 框架下应用子事务屏障的类
'apply' => [],
],
// HTTP 协议下 Guzzle 客户端的通用配置
'guzzle' => [
'options' => [],
],
];
配置中间件
在使用之前,需要配置 DtmClientMiddlewareDtmMiddleware
<?php
namespace App\Controller;
use DtmClient\TCC;
use DtmClient\TransContext;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Throwable;
#[Controller(prefix: '/tcc')]
class TccController
{
protected string $serviceUri = 'http://127.0.0.1:9501';
#[Inject]
protected TCC $tcc;
#[GetMapping(path: 'successCase')]
public function successCase()
{
try {
$this->tcc->globalTransaction(function (TCC $tcc) {
// 创建子事务 A 的调用数据
$tcc->callBranch(
// 调用 Try 方法的参数
['amount' => 30],
// Try 方法的 URL
$this->serviceUri . '/tcc/transA/try',
// Confirm 方法的 URL
$this->serviceUri . '/tcc/transA/confirm',
// Cancel 方法的 URL
$this->serviceUri . '/tcc/transA/cancel'
);
// 创建子事务 B 的调用数据,以此类推
$tcc->callBranch(
['amount' => 30],
$this->serviceUri . '/tcc/transB/try',
$this->serviceUri . '/tcc/transB/confirm',
$this->serviceUri . '/tcc/transB/cancel'
);
});
} catch (Throwable $e) {
var_dump($e->getMessage(), $e->getTraceAsString());
}
// 通过 TransContext::getGid() 获得 全局事务ID 并返回
return TransContext::getGid();
}
}
Hyperf가 아닌 프레임워크에서 사용하는 경우 ./vendor를 복사할 수 있습니다. /dtm/dtm-client/publish/dtm.php 파일을 해당 구성 디렉터리에 복사합니다.
namespace App\Controller;
use DtmClient\Saga;
use DtmClient\TransContext;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
#[Controller(prefix: '/saga')]
class SagaController
{
protected string $serviceUri = 'http://127.0.0.1:9501';
#[Inject]
protected Saga $saga;
#[GetMapping(path: 'successCase')]
public function successCase(): string
{
$payload = ['amount' => 50];
// 初始化 Saga 事务
$this->saga->init();
// 增加转出子事务
$this->saga->add(
$this->serviceUri . '/saga/transOut',
$this->serviceUri . '/saga/transOutCompensate',
$payload
);
// 增加转入子事务
$this->saga->add(
$this->serviceUri . '/saga/transIn',
$this->serviceUri . '/saga/transInCompensate',
$payload
);
// 提交 Saga 事务
$this->saga->submit();
// 通过 TransContext::getGid() 获得 全局事务ID 并返回
return TransContext::getGid();
}
}
미들웨어 구성사용하기 전에 DtmClientMiddlewareDtmMiddleware
미들웨어를 서버의 글로벌 미들웨어로 구성해야 합니다. 이 미들웨어는 PSR-15 사양을 지원하며 이를 지원하는 다양한 프레임워크에 적용할 수 있습니다. 사양. .
Hyperf의 미들웨어 구성에 대해서는 Hyperf 설명서 - 미들웨어 장을 참조하세요.
Usagedtm-client는 사용이 매우 간단합니다. 우리는 더 나은 이해와 디버깅을 돕기 위해 샘플 프로젝트 dtm-php/dtm-sample을 제공합니다.
이 구성 요소를 사용하기 전에 더 자세한 이해를 위해 공식 DTM 설명서를 읽어 보는 것이 좋습니다.
TCC 모드는 매우 인기 있는 유연한 거래 솔루션입니다. TCC의 개념은 Try-Confirm-Cancel의 약어로 구성됩니다. 2007년 Pat Helland가 처음 발표했습니다. "Life"라는 제목의 논문에서 제안되었습니다. 분산 트랜잭션 너머: 배도자의 의견".
TCC의 3단계시도 단계: 실행 시도, 모든 비즈니스 점검 완료(일관성), 필요한 비즈니스 자원 확보(준격리) 확인 단계: 모든 지점의 시도가 성공하면 이동 확인 단계. 확인은 비즈니스 확인 없이 실제로 비즈니스를 실행하며 Try 단계에서 예약된 비즈니스 리소스만 사용합니다. 취소 단계: 모든 분기의 시도 중 하나가 실패하면 취소 단계로 이동합니다. 취소는 시도 단계 동안 예약된 비즈니스 리소스를 해제합니다.
은행간 이체와 유사한 비즈니스를 수행하려는 경우 이체(TransOut)와 이체(TransIn)는 서로 다른 마이크로서비스에 있습니다. 성공적으로 완료된 TCC 거래의 일반적인 시퀀스 다이어그램은 다음과 같습니다.
코드 예제
다음은 Hyperf 프레임워크에서 사용하는 방법을 보여줍니다. 다른 프레임워크도 비슷합니다.
rrreeeSaga 모드
Saga 모드는 분산 트랜잭션 분야에서 가장 유명한 솔루션 중 하나이며 또한 매우 주요 시스템에서 인기가 있으며 Hector Garcaa-Molrna와 Kenneth Salem이 쓴 1987년 SAGAS 논문에 처음 등장했습니다. Saga는 궁극적으로 일관된 트랜잭션이자 유연한 트랜잭션입니다. Saga는 일련의 로컬 트랜잭션으로 구성됩니다. 각 로컬 트랜잭션이 데이터베이스를 업데이트한 후 Saga 글로벌 트랜잭션에서 다음 로컬 트랜잭션의 실행을 트리거하는 메시지나 이벤트를 게시합니다. 일부 비즈니스 규칙을 충족할 수 없어 로컬 트랜잭션이 실패하는 경우 Saga는 실패한 트랜잭션 이전에 성공적으로 커밋된 모든 트랜잭션에 대해 보상 작업을 수행합니다. 따라서 Saga 모드와 TCC 모드를 비교할 때 리소스 예약 단계가 부족하여 롤백 로직을 구현하는 것이 더 번거로운 경우가 많습니다.
사가 하위 거래 분할- 예를 들어 계좌 A에서 계좌 B로 30위안을 이체하는 은행간 이체와 유사한 업무를 수행하려고 합니다. 사가 거래의 원칙에 따라 전체를 분할합니다. 글로벌 거래 다음 서비스의 경우:
-
- TransOut 서비스, 계정 A에서 30위안을 공제하는 작업이 수행됩니다.
- TransOutCompensate 서비스, 위의 이체 작업을 롤백합니다. 즉, 계정 A가 30위안 증가합니다
TransIn 서비스, 여기 B 계정이 30위안 증가합니다 이체 보상(TransInCompensate) 서비스, 위의 이체 작업이 롤백됩니다. 즉, B 계정이 30위안 감소됩니다
전체 거래의 논리
이체 실행 성공 => 이체 성공 => 글로벌 트랜잭션 완료
B 계좌로 이체 오류 등 중간에 오류가 발생하면 실행된 브랜치의 보상 작업이 호출되며, 즉:
🎜이체 실행 성공 => 이체 실행 실패 => 보상 이체 실행 성공 => 이체 보상 성공 => 글로벌 트랜잭션 롤백 완료🎜🎜다음은 성공적으로 완료된 SAGA의 일반적인 타이밍 다이어그램입니다. 거래:🎜
代码示例
以下展示在 Hyperf 框架中的使用方法,其它框架类似
namespace App\Controller;
use DtmClient\Saga;
use DtmClient\TransContext;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
#[Controller(prefix: '/saga')]
class SagaController
{
protected string $serviceUri = 'http://127.0.0.1:9501';
#[Inject]
protected Saga $saga;
#[GetMapping(path: 'successCase')]
public function successCase(): string
{
$payload = ['amount' => 50];
// 初始化 Saga 事务
$this->saga->init();
// 增加转出子事务
$this->saga->add(
$this->serviceUri . '/saga/transOut',
$this->serviceUri . '/saga/transOutCompensate',
$payload
);
// 增加转入子事务
$this->saga->add(
$this->serviceUri . '/saga/transIn',
$this->serviceUri . '/saga/transInCompensate',
$payload
);
// 提交 Saga 事务
$this->saga->submit();
// 通过 TransContext::getGid() 获得 全局事务ID 并返回
return TransContext::getGid();
}
}