3秒でわかる
呼び出した側が結果を待つ形式のやり取り。UML シーケンス図では塗りつぶした矢じりの実線で描き、処理の流れの順序を明確にします。
もう少し詳しく
どういうものか
同期メッセージは、送り手が相手の処理が終わって応答が返るまで次へ進まない形式のやり取りです。UML のシーケンス図では、塗りつぶした三角の矢じりを持つ実線の矢印で表します。返りの応答は破線の矢印で描き、省略されることもあります。
通常の関数呼び出し、データベースへの問い合わせ、応答を待つ HTTP リクエストは、いずれも同期メッセージとして描かれます。
なぜ必要か
図の上で同期か非同期かを区別できると、どこで待ちが発生するかが読み取れます。3 つのサービスを順に同期で呼ぶ設計なら、応答時間はその 3 つの合計になります。1 つが遅いだけで全体が遅くなることが、線の形を見た時点で分かります。
設計レビューで「ここは待つ必要があるか」を議論する材料にもなります。メール送信のように結果を待たなくてよい処理まで同期で描かれていれば、非同期に回す候補として拾えます。
具体例
注文処理を図にすると下記のようになります。
利用者 注文API 在庫サービス 決済サービス
| | | |
|--注文---> | | | 実線・塗り矢じり = 同期
| |--在庫確認--> | |
| |<---- 応答 ----| | 破線 = 応答
| |--------- 決済実行 ----------> |
| |<-------- 応答 ---------------- |
|<-- 結果 -- | | |
| |==メール送信==>| | 線の矢じりが開いていれば非同期コードに落とすと、同期は結果を受け取ってから次行へ進む形になります。
Stock stock = stockService.check(orderId); // 応答を待つ
Payment result = paymentService.pay(orderId, stock.getAmount());
mailQueue.enqueue(orderId); // 待たずに次へつまずきやすいところ
実線と破線の使い分けを取り違える例が多くあります。実線は呼び出し、破線は戻りです。非同期メッセージは実線のまま矢じりだけが線状(開いた形)になります。矢じりが塗られているかどうかが同期と非同期の分かれ目です。
活性区間(ライフライン上の細長い長方形)の描き方も間違えやすい部分です。同期メッセージでは、呼ばれた側の活性区間が始まってから応答が返るまで、呼んだ側の活性区間も続いています。応答前に呼び出し元の区間を閉じてしまうと、待っていないという意味になります。
似た用語との違い
| 種類 | 記法 | 送り手の挙動 |
|---|---|---|
| 同期メッセージ | 実線 + 塗りつぶした矢じり | 応答まで待つ |
| 非同期メッセージ | 実線 + 開いた矢じり | 待たずに進む |
| 応答メッセージ | 破線 + 開いた矢じり | 戻り値を表す |
覚え方
矢じりが塗りつぶされている線は「詰まっている」ので進めない、と覚えると同期と非同期を取り違えません。