doc.dev1x.org

Saga

1. 背景

複数のマイクロサービスを横断したトランザクションを実現したい

2. 課題

如何にしてマイクロサービスを横断したトランザクション/ロールバックを実装するか

3. 解決策

各マイクロサービスにロールバックAPIを実装する

ローカルトランザクションを管理するモジュールを実装する

4. メリット

5. デメリット

6. 注意事項

参考資料

Appendix-1 シンプルなSagaパターンのサンプル実装

class SagaOperator:
    def __init__(self, *services):
        self.services = services
        self.completed = []

    def run(self):
        try:
            self._execute()
        catch:
            self._rollback()

    def _execute(self):
        for s in self.service:
            s.execute()
            self.completed.append(s)

    def _rollback(self):
        for s in self.completed:
            s.rollback()

class Service(metaclass=ABCMeta):
    @abstractmethod
    def execute(self):
        """ マイクロサービスにデータを登録する処理 """
        pass

    @abstractmethod
    def rollback(self):
        """ マイクロサービスに登録したデータを削除する処理 """
        pass

class Service01(Service):
    def execute(self):
        # APIにデータを送信して結果を評価する処理が書いてあると考えよ
        print("Service01 complete")

    def rollback(self):
        # APIにデータの削除を要求する処理が書いてあると考えよ
        print("Service01 rollback")

class Service02(Service):
    def execute(self):
        # APIにデータを送信して結果を評価する処理が書いてあると考えよ
        print("Service02 complete")

    def rollback(self):
        # APIにデータの削除を要求する処理が書いてあると考えよ
        print("Service02 rollback")

class Service03(Service):
    def execute(self):
        # APIにデータを送信して結果を評価する処理が書いてあると考えよ
        print("Service03 complete")

    def rollback(self):
        # APIにデータの削除を要求する処理が書いてあると考えよ
        print("Service03 rollback")


if __name__ == '__main__':
    op = SagaOperator(
        Service01(),
        Service02(),
        Service03(),
    )
    op.run()