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 目次
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
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
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が効果的に働くのか?
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 …)
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)
Correction Don`t select tables belonging to aggregate to recreate an aggregate. Select tables belonging to an aggregate itself only. 25 集約の再構築には、自身に所属するテーブルだけを使う
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!
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 独自のライフサイクルを持つ値オブジェクトを、新たな集 約として抽出する
Correction Issue a query only one time and raise a deadlock alert to engineers. Retry queries having deadlock lisk automatically. 32 ロックが競合する可能性のあるクエリは、自動的にリトラ イする
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 リポジトリ実装の勘所
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 トランザクション分離レベルの変更を検討する