Upgrade to Pro — share decks privately, control downloads, hide ads and more …

デッドロックを回避するリポジトリ実装の勘所

男爵
April 16, 2023

 デッドロックを回避するリポジトリ実装の勘所

ScalaMatsuri2023の登壇資料です。

男爵

April 16, 2023
Tweet

More Decks by 男爵

Other Decks in Programming

Transcript

  1. Points of implementation of
    Repository to avoid Deadlock
    @dnskimox
    デッドロックを回避する
    リポジトリ実装の勘所

    View Slide

  2. HELLO!
    男爵 @dnskimox
    Dansyaku / Tanga Kenichi
    A backend developer at
    2
    自己紹介

    View Slide

  3. Table of Contents
    ✘ Sample of DDD like domain model
    ✘ Implementation policy of Repository
    ✘ Making persistence of Value Object
    ✘ Deadlock examples and corrections
    ✘ Points of implementation of Repository
    ✘ More fundamental solutions of deadlock
    3
    目次

    View Slide

  4. Preconditions of System
    ✘ RDB is Amazon Aurora (compatible with
    MySQL 5.7).
    ✘ Default storage engine is InnoDB
    ✘ Default transaction separation level is
    Repeatable Read.
    ✘ Primary keys in tables are UUID.
    4
    MySQL 5.7、InnoDB、リピータブルリード、UUID

    View Slide

  5. Sample Domain Model
    like DDD
    DDD風のサンプルドメインモデル

    View Slide

  6. CloudSign
    Salesforce
    Dashboard(SPA)
    Client Service
    MakeInvoice
    架空の請求書発行SaaS

    View Slide

  7. 7
    請求書、カスタムフィールド、カスタムフィールドマス
    ター

    View Slide

  8. 8
    請求書テーブル、カスタムフィールドテーブル、カスタム
    フィールドマスターテーブル

    View Slide

  9. Implementation policy
    of Repository
    リポジトリ実装の方針

    View Slide

  10. 10
    参考書籍:実践ドメイン駆動設計

    View Slide

  11. 11
    集約毎とリポジトリを一対一で用意する

    View Slide

  12. 12
    実装クラスはSQLを発行する機能を持ち、ロックありで集約を
    取得した場合、SELECT 〜 FOR UPDATE文を発行

    View Slide

  13. Making persistence
    of Value Object
    値オブジェクトの永続化について

    View Slide

  14. 14
    参考書籍:エンタープライズアプリケーションアーキテク
    チャパターン

    View Slide

  15. 15
    依存オブジェクトは唯一つの親を持つ
    親以外からの参照は存在しない
    - A dependent must have exactly one
    owner.
    - There must be no references from
    any object other than the owner to
    the dependent
    Dependent Mapping

    View Slide

  16. Update logic for custom fields is very simple
    16
    DELETE FROM custom_fields where invoice_id = X;
    INSERT INTO custom_fields (id, invoice_id, …) VALUES (uuid(), X, …);
    INSERT INTO custom_fields (id, invoice_id, …) VALUES (uuid(), X, …);
    値オブジェクトの更新は非常にシンプル

    View Slide

  17. Why that sql is effectively update value objects?
    ✘ Value Object don't have an identity.
    ✘ A permanent Value Object necessarily
    depends on one parent entity.
    ✘ Value Object is immutable.
    17
    なぜこのSQLが効果的に働くのか?

    View Slide

  18. Deadlock examples and
    corrections
    デッドロックの実例と修正方法

    View Slide

  19. 1. Illegal aggregate boundary
    about table reference
    テーブル参照における集約の境界違反

    View Slide

  20. 20
    ロックの競合が発生しやすいクエリ
    TX1 > SELECT * FROM invoices iv
    JOIN custom_field cf ON cf.invoice_id = iv.id
    JOIN custom_field_master cfm ON cf.master_id = cfm.id
    WHERE iv.id = X FOR UPDATE;
    TX2 > SELECT * FROM invoices iv
    JOIN custom_field cf ON cf.invoice_id = iv.id
    JOIN custom_field_master cfm ON cf.master_id = cfm.id
    WHERE iv.id = Y FOR UPDATE;
    TX2 > (Waiting for lock granted …)

    View Slide

  21. 21
    ドメインモデルを再確認

    View Slide

  22. 22
    custom_field_mastersの値を共有しているzuzu a

    View Slide

  23. 23
    custom_fields側に値を非正規化する

    View Slide

  24. 24
    ロックの競合が発生しづらいクエリ
    TX1 > select * from invoices iv
    join custom_field cf on cf.invoice_id = iv.id
    where iv.id = X fo update;
    TX2 > select * from invoices iv
    join custom_field cf on cf.invoice_id = iv.id
    where iv.id = Y fo update;
    TX2 > (Query returns immediately)

    View Slide

  25. Correction
    Don`t select tables belonging to aggregate to
    recreate an aggregate.
    Select tables belonging to an aggregate itself
    only.
    25
    集約の再構築には、自身に所属するテーブルだけを使う

    View Slide

  26. 2. Gaplock problem on
    DELETE/INSERT approach
    DELETE/INSERT方式におけるギャップロックの問題

    View Slide

  27. 27
    デッドロックの発生しやすいクエリ
    TX1 > select * from custom_fields where invoice_id = X for update;
    TX1 > delete from custom_fields where invoice_id = X;
    TX1 > insert into custom_fields values (uuid(), X, …);
    TX1 > (Waiting for lock granted …)
    TX2 > select * from custom_fields where invoice_id = Y for update;
    TX2 > delete from custom_fields where invoice_id = Y;
    TX2 > insert into custom_fields values (uuid(), Y, …);
    TX2 > Deadlock Detected!

    View Slide

  28. 28
    クラス図(修正前)zuzu a

    View Slide

  29. 29
    クラス図(修正後)zuzu

    View Slide

  30. Correction
    Mix in many objects into aggregate in spite of
    difference of its life cycle
    Extract value object having its own life cycle
    from aggregate as a new aggregate.
    30
    独自のライフサイクルを持つ値オブジェクトを、新たな集
    約として抽出する

    View Slide

  31. 3. Other complicated
    deadlock problems
    その他の込み入った問題たち

    View Slide

  32. Correction
    Issue a query only one time and raise a
    deadlock alert to engineers.
    Retry queries having deadlock lisk
    automatically.
    32
    ロックが競合する可能性のあるクエリは、自動的にリトラ
    イする

    View Slide

  33. Points of implementation
    of Repository
    リポジトリ実装の勘所

    View Slide

  34. Points of implementation of Repository
    ✘ Don’t share a database row with another
    aggregate.
    ✘ If another lifecycle is detected extract a new
    aggregate.
    ✘ Retry failed transaction for deadlock.
    34
    リポジトリ実装の勘所

    View Slide

  35. More fundamental solutions
    of deadlock
    より根本的なデッドロック対策

    View Slide

  36. More fundamental solutions of deadlock
    ✘ Consider to change transaction separation
    level.
    Do you really need that level of integrity?
    Think about boundary of aggregate.
    36
    トランザクション分離レベルの変更を検討する

    View Slide

  37. THANKS!
    Any questions?
    You can find me at
    ✘  @dnxkimox
    ✘ https:/
    /dnskimox.hateblo.jp
    ✘ https:/
    /note.com/dnskimo
    37
    ご清聴ありがとうございました!

    View Slide

  38. Reference documents
    ✘ Implementing Domain-Driven Design
    ✘ Patterns of Enterprise Application
    Architecture
    38
    参考文献

    View Slide