spring-boot-saga-pattern
Spring Bootマイクロサービスにおける分散トランザクションをSagaパターンで実装するためのスキルです。複数サービスにまたがる分散トランザクションの構築、補償トランザクションの処理、結果整合性の確保、またはKafka・RabbitMQ・Axon Frameworkを用いたコレオグラフィ型・オーケストレーション型Sagaの実装時に活用できます。
description の原文を見る
Provides distributed transaction patterns using the Saga Pattern for Spring Boot microservices. Use when implementing distributed transactions across services, handling compensating transactions, ensuring eventual consistency, or building choreography or orchestration-based sagas with Kafka, RabbitMQ, or Axon Framework.
SKILL.md 本文
Spring Boot Saga Pattern
概要
Sagaパターンを使用したマイクロサービス間の分散トランザクション実装。2フェーズコミットをローカルトランザクションと補償アクションのシーケンスで置き換えます。Kafka、RabbitMQ、またはAxon Frameworkを使用したコレオグラフィ(イベント駆動)およびオーケストレーション(集中型コーディネータ)アプローチをサポートします。
使用時機
- 複数のマイクロサービス間での分散トランザクションの構築
- 2フェーズコミット(2PC)をより拡張性の高いソリューションで置き換える
- サービス障害時のトランザクションロールバック処理
- マイクロサービスアーキテクチャにおける結果整合性の確保
- 失敗した操作に対する補償トランザクションの実装
- 複数のサービスにまたがる複雑なビジネスプロセスの調整
トリガーフレーズ: 分散トランザクション、sagaパターン、補償トランザクション、マイクロサービストランザクション、結果整合性、サービス間のロールバック、オーケストレーションパターン、コレオグラフィパターン
手順
1. トランザクションフローの設計
操作のシーケンスと対応する補償トランザクションをマッピングします:
Order → Payment → Inventory → Shipment
↓ ↓ ↓ ↓
Cancel Refund Release Cancel
検証: すべての前進ステップに対応する補償が存在することを確認します。
2. 実装方法の選択
| アプローチ | ユースケース | スタック |
|---|---|---|
| コレオグラフィ | グリーンフィールド、参加者が少ない | Spring Cloud Stream + Kafka/RabbitMQ |
| オーケストレーション | 複雑なワークフロー、既存システム | Axon Framework、Eventuate Tram、Camunda |
検証: 方法を選択する前に、チームの専門知識とシステムの複雑性を確認します。
3. ローカルトランザクション付きサービスの実装
各サービスはローカルACIDトランザクションをアトミックに完了します:
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
private final KafkaTemplate<String, Object> kafka;
@Transactional
public Order createOrder(CreateOrderCommand cmd) {
Order order = orderRepository.save(new Order(cmd.orderId(), cmd.items()));
kafka.send("order.created", new OrderCreatedEvent(order.getId(), order.getItems()));
return order;
}
}
検証: イベント発行前にローカルトランザクションがコミットされることをテストします。
4. 補償トランザクションの実装
すべての前進操作には、べき等な補償が必要です:
@Service
@RequiredArgsConstructor
public class PaymentService {
private final PaymentRepository paymentRepository;
private final KafkaTemplate<String, Object> kafka;
public void processPayment(PaymentRequest request) {
Payment payment = paymentRepository.save(new Payment(request.orderId(), request.amount()));
kafka.send("payment.processed", new PaymentProcessedEvent(payment.getId(), request.orderId()));
}
@Transactional
public void refundPayment(String paymentId) {
paymentRepository.findById(paymentId)
.ifPresent(p -> {
p.setStatus(REFUNDED);
paymentRepository.save(p);
kafka.send("payment.refunded", new PaymentRefundedEvent(paymentId));
});
}
}
検証: 補償が何度も安全に実行できることを確認します(べき等性)。
5. メッセージブローカーのセットアップ
べき等なコンシューマー付きKafkaを構成します:
@Configuration
@EnableKafka
public class KafkaConfig {
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory(
ConsumerFactory<String, Object> consumerFactory) {
ConcurrentKafkaListenerContainerFactory<String, Object> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory);
factory.setCommonErrorHandler(new DefaultErrorHandler());
return factory;
}
}
検証: トランザクションIDを有効にし、正確に1回のセマンティクスを確認します。
6. Sagaオーケストレータの実装(オーケストレーションのみ)
@Service
@RequiredArgsConstructor
public class OrderSagaOrchestrator {
private final KafkaTemplate<String, Object> kafka;
private final SagaStateRepository sagaStateRepo;
public void startSaga(OrderRequest request) {
String sagaId = UUID.randomUUID().toString();
sagaStateRepo.save(new SagaState(sagaId, STARTED, LocalDateTime.now()));
kafka.send("saga.order.start", new StartOrderSagaCommand(sagaId, request));
}
@KafkaListener(topics = "payment.failed")
public void handlePaymentFailed(PaymentFailedEvent event) {
kafka.send("order.compensate", new CompensateOrderCommand(event.getSagaId()));
kafka.send("inventory.compensate", new ReleaseInventoryCommand(event.getSagaId()));
sagaStateRepo.updateStatus(event.getSagaId(), FAILED);
}
}
検証: コマンド送信前にsagaの状態が永続化されることを確認します。各障害パスで補償トリガーをチェックします。
7. イベントハンドラの実装(コレオグラフィのみ)
@Service
public class OrderEventHandler {
private final OrderService orderService;
private final KafkaTemplate<String, Object> kafka;
@KafkaListener(topics = "payment.processed", groupId = "order-service")
public void onPaymentProcessed(PaymentProcessedEvent event) {
try {
InventoryReservedEvent result = orderService.reserveInventory(event.toInventoryRequest());
kafka.send("inventory.reserved", result);
} catch (InsufficientInventoryException e) {
kafka.send("inventory.insufficient", new InsufficientInventoryEvent(event.getOrderId(), event.getPaymentId()));
}
}
}
検証: 各イベントハンドラが次のステップまたは補償を正しくトリガーすることをテストします。
8. モニタリングと可観測性の追加
@Configuration
public class SagaMetricsConfig {
@Bean
public MeterRegistry meterRegistry() {
return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
}
}
追跡対象:saga実行時間、補償数、障害率、スタックしたsaga。
検証: 予想期間を超えたsagaのアラートを設定します。
ベストプラクティス
設計:
- 補償トランザクションをべき等にする(データベース制約または重複排除テーブルを使用)
- イミュータブルイベント(Javaレコード)を使用して意図しない変更を防ぐ
- リカバリのためにsaga状態を永続ストレージに保存する
エラーハンドリング:
- サービス間呼び出しに対してサーキットブレーカーを実装する
- リトライ制限を超えたメッセージに対してデッドレターキューを使用する
- sagaステップごとに適切なタイムアウトを設定する(デフォルト30秒、構成可能)
モニタリング:
- saga状態を追跡:PENDING、COMPLETED、COMPENSATING、FAILED
- 補償実行時間を監視する
- sagaがSLA期間を超えた場合はアラートを出す
制約と警告
- すべての前進トランザクションに対応する補償トランザクションが必須
- 補償トランザクションはリトライシナリオに対応するためべき等である必須
- saga状態は障害とリカバリに対応するため永続化が必須
- sagaの参加者間での同期通信は決して使用しない
- sagaは結果整合性を提供し、強い整合性は提供しない
- すべての障害シナリオ(部分障害を含む)をテストする
- 複雑なオーケストレーションにはAxon FrameworkまたはEventicateを検討する
- メッセージブローカーの高可用性を確保する
例
コレオグラフィベースのSaga
// Application.java
@SpringBootApplication
@EnableKafka
@EnableKafkaListeners
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
// イベントクラス(イミュータブル)
public record OrderCreatedEvent(String orderId, List<OrderItem> items) {}
public record PaymentProcessedEvent(String paymentId, String orderId) {}
public record InventoryReservedEvent(String reservationId, String orderId) {}
public record PaymentFailedEvent(String orderId, String reason) {}
public record InsufficientInventoryEvent(String orderId, String paymentId) {}
// 補償付きOrderService
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
private final KafkaTemplate<String, Object> kafka;
@KafkaListener(topics = "payment.failed", groupId = "order-service")
public void handleCompensation(PaymentFailedEvent event) {
orderRepository.findByOrderId(event.orderId())
.ifPresent(order -> {
order.setStatus(CANCELLED);
orderRepository.save(order);
});
}
}
Axon Frameworkを使用したオーケストレーションベースのSaga
// Command
@Aggregate
public class OrderAggregate {
@AggregateIdentifier
private String orderId;
@CommandHandler
public OrderAggregate(CreateOrderCommand cmd) {
apply(new OrderCreatedEvent(cmd.orderId(), cmd.items()));
}
@EventSourcingHandler
public void on(OrderCreatedEvent event) {
this.orderId = event.orderId();
}
@CommandHandler
public void handle(CancelOrderCommand cmd) {
apply(new OrderCancelledEvent(cmd.orderId(), cmd.reason()));
}
}
リファレンス
Saga Pattern DefinitionChoreography ImplementationOrchestration ImplementationCompensating TransactionsState ManagementError Handling and RetryTesting StrategiesPitfalls and SolutionsExamples
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- giuseppe-trisciuoglio
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/giuseppe-trisciuoglio/developer-kit / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。