Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
並行性の問題を防げ!実践トランザクション入門
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Shoichi Ochi
October 02, 2026
Technology
300
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
並行性の問題を防げ!実践トランザクション入門
PHPカンファレンス愛媛 2026 登壇資料
Shoichi Ochi
October 02, 2026
More Decks by Shoichi Ochi
See All by Shoichi Ochi
Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
1
1k
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
770
Prevent Concurrency Problems! A Practical Introduction to Transactions
occhi
0
30
ノイジーネイバー問題を解決する 公平なキューイング
occhi
0
250
高速化&コスト半減!? GitHub Actionsの サードパーティマネージドランナーの比較
occhi
1
970
HTTPじゃ遅すぎる! SwitchBotを自作ハブで動かして学ぶBLE通信
occhi
0
2.3k
Other Decks in Technology
See All in Technology
コンテナ運用におけるネットワーク・コンテナコストの削減方法/How to Reduce Network and Container Costs in Container Operations
masakiokuda
2
370
Codex を使った障害対応机上演習の実際
orgachem
PRO
0
210
LLM Content Moderationを支える評価・改善ループの実践
suikabar
1
260
その Valkey 使いこなしていますか?
onk
PRO
5
1.8k
PHPカンファレンス関西の招待状 / Invitation to PHP Conference Kansai
ykanoh
0
220
React改造してみた
tsukina_7mochi
0
150
DGX Spark でどこまでハッキングができるのか?
kash1064
3
1.4k
トークン化預金DCJPYの取り組みと活用ユースケース
finengine
0
210
20261017福岡devIO 「AIは"良いダッシュボード"を作れるか?
jtakeda
0
220
Benchmarking Disaggregated Serving on vLLM + Dynamo with a Real Coding-Agent Workload
nttcom
1
210
古い指輪から広がった JAVA コミュニティ とのつながり
yamad
0
130
大型犬好きによるPugの紹介
yamanoku
1
160
Featured
See All Featured
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.2k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.7k
Marketing to machines
jonoalderson
1
5.9k
The browser strikes back
jonoalderson
0
1.8k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Designing for Performance
lara
612
70k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
570
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Practical Orchestrator
shlominoach
192
12k
Ethics towards AI in product and experience design
skipperchong
2
440
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
570
Transcript
並行性の問題を防げ! 実践トランザクション入門 Shoichi Ochi (@occhi) PHPカンファレンス愛媛2026 2026-10-03
自己紹介 おち しょういち 越智 翔一 SmartBank, Inc. Software Engineer 出身:
愛媛県西条市 趣味: 筋トレ @ochi11181101 @sho-work 2
3
トランザクション 4
Introduction 「トランザクション」 複数の読み書きを、 1つの論理的な処理単位と して扱う仕組み。 トランザクション中のすべての読み書きは、 1つ の処理単位として扱われ、オールオアナッシン グの保証を提供してくれる。 つまり、すべて成功するか(
commit)、すべて なかった(rollback)ことにするかしかない。 5
Introduction 「トランザクション」 複数の読み書きを、 1つの論理的な処理単位と して扱う仕組み。 トランザクション中のすべての読み書きは、 1つ の処理単位として扱われ、オールオアナッシン グの保証を提供してくれる。 複数のクエリを、
BEGIN ~ COMMITで囲む つまり、すべて成功するか( commit)、すべて なかった(rollback)ことにするかしかない。 6
今回はそんなトランザクションが、 複数実行された時に起こる問題の話 7
では、実際にどんな問題が起こる?🤔 8
簡単な例を見てみよう!💪💪 9
Introduction 並行性の問題の簡単な例 カウンタの同一レコード更新をしようとする 2つのトランザクションを考える * https://www.oreilly.co.jp/books/9784873118703/ 10
Introduction 並行性の問題の簡単な例 カウンタの同一レコード更新をしようとする 2つのトランザクションを考える BEGIN * https://www.oreilly.co.jp/books/9784873118703/ COMMIT 11
Introduction 並行性の問題の簡単な例 カウンタの同一レコード更新をしようとする 2つのトランザクションを考える BEGIN * https://www.oreilly.co.jp/books/9784873118703/ COMMIT 12
Introduction 並行性の問題の簡単な例 カウンタの同一レコード更新をしようとする 2つのトランザクションを考える Tx A Tx B * https://www.oreilly.co.jp/books/9784873118703/
13
Introduction 並行性の問題の簡単な例 どちらのユーザーも現在のカウンタ +1したい よって、以下のようになっていて欲しい ・ユーザー 1のCOMMIT直後には 43 ・ユーザー 2のCOMMIT直後には
44 * https://www.oreilly.co.jp/books/9784873118703/ 14
Introduction 並行性の問題の簡単な例 1. Tx Aが現在のカウンタを読む( =42) * https://www.oreilly.co.jp/books/9784873118703/ 15
Introduction 並行性の問題の簡単な例 1. Tx Aが現在のカウンタを読む(=42) 2. Tx Bが現在のカウンタを読む( =42) *
https://www.oreilly.co.jp/books/9784873118703/ 16
Introduction 並行性の問題の簡単な例 1. Tx Aが現在のカウンタを読む(=42) 3. カウンタを 42+1し、43でUPDATE 2. Tx
Bが現在のカウンタを読む(=42) * https://www.oreilly.co.jp/books/9784873118703/ 17
Introduction 並行性の問題の簡単な例 1. Tx Aが現在のカウンタを読む(=42) 3. カウンタを42+1し、43でUPDATE 2. Tx Bが現在のカウンタを読む(=42)
* https://www.oreilly.co.jp/books/9784873118703/ 4. カウンタを 42+1し、43でUPDATE 18
Introduction 並行性の問題の簡単な例 最終結果が 44ではなく、 43になってしまった! 😭 3. カウンタを42+1し、43でUPDATE 4. カウンタを
42+1し、43でUPDATE * https://www.oreilly.co.jp/books/9784873118703/ 19
むむむ・・・🤔 2020
どうやって防げばいいんやろか?🤔 2121
今日のトーク 22
今日紹介するトランザクション分離レベルとレース条件 23
今日紹介するトランザクション分離レベルとレース条件 24
今日のトーク 25
1. トランザクション分離レベル 26
トランザクション分離レベル
トランザクション分離レベル 28
分離レベルは「他のTxの変更が、いつから見えるか」の設定 29
他の Tx の変更が見え始めるタイミングは、分離レベルで違う 30
他の Tx の変更が見え始めるタイミングは、分離レベルで違う 31
他の Tx の変更が見え始めるタイミングは、分離レベルで違う 32
トランザクション分離レベル 33
Serializableの実現方法は 3 つある 34
Serializableの実現方法は 3 つあり、どれも見え方が異なる 35
完全な順次実行:そもそも同時に走らせない 36
完全な順次実行:そもそも同時に走らせない 37
Serializableの実現方法は 3 つあり、どれも見え方が異なる 38
ロックには、共有ロックと排他ロックがある 39
2PL:ロックを取って、競合する読み書きを待たせる 40
2PL:ロックを取って、競合する読み書きを待たせる 41
2PL:ロックを取って、競合する読み書きを待たせる 42
2PL:ロックを取って、競合する読み書きを待たせる 43
2PL:ロックを取って、競合する読み書きを待たせる 44
Serializableの実現方法は 3 つあり、どれも見え方が異なる 45
SSI(直列化可能なスナップショット分離):スナップショットから更新されていたらロールバックさせる 46
SSI(直列化可能なスナップショット分離):スナップショットから更新されていたらロールバックさせる 47
SSI(直列化可能なスナップショット分離):スナップショットから更新されていたらロールバックさせる 48
SSI(直列化可能なスナップショット分離):スナップショットから更新されていたらロールバックさせる 49
SSI(直列化可能なスナップショット分離):スナップショットから更新されていたらロールバックさせる 50
今日のトーク 51
2. 並行性の問題 52
並行性の問題の全体像 53
問題ごとに「どのレベルから防げるか」を表に埋めていく 54
同じ 1 行を、並行して読み書きする場合に起こる問題 55
ここからしばらくは、accounts テーブルで考える 56
Dirty Write:未コミットの値を、別のTxが上書きしてしまう 57
Dirty Write:未コミットの値を、別のTxが上書きしてしまう 58
Dirty Write:未コミットの値を、別のTxが上書きしてしまう 59
Dirty Write:未コミットの値を、別のTxが上書きしてしまう 60
Dirty Write:未コミットの値を、別のTxが上書きしてしまう 61
Dirty Write は、どの分離レベルでも防がれる 62
Dirty Write の防ぎ方:書き込む行のロックを COMMIT まで持つ 63
Dirty Read:未コミットの値を読んでしまう 64
Dirty Read:未コミットの値を読んでしまう 65
Dirty Read:未コミットの値を読んでしまう 66
Dirty Read:未コミットの値を読んでしまう 67
Dirty Read:未コミットの値を読んでしまう 68
Dirty Read は Read Uncommitted で起き、Read Committed 以上で防げる 69
Lost Update:古い値を前提に上書きして、更新が消える 70
Lost Update は Snapshot Isolation 以下で起きうる(DB による) https://www.postgresql.org/docs/current/transaction-iso.html 71
複数の行にまたがる整合性が崩れる問題 72
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 73
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 74
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 75
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 76
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 77
Read Skew:1つのTx内で、異なる時点のコミット済みデータを読んでしまう 78
Read Skew は Read Committed 以下で起き、Snapshot Isolation 以上で防げる 79 79
ここからは budgets テーブルで考える 80
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 81
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 82
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 83
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 84
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 85
部署の予算:どちらも「あと 20 使える」と判断して、合計が上限を超える 86
更新は消えていない。壊れたのは「読んだ前提」 87
Write Skew は「Observe → Decide → Mutate」の流れで起きる 88
Write Skew は「Observe → Decide → Mutate」の流れで起きる 89
Write Skew は「Observe → Decide → Mutate」の流れで起きる 90
2 つの Tx が同じ古い前提を観測すると、組み合わせた結果として不変条件が壊れる 91
同じ形の問題は、身近にいくつもある 92
会議室予約は bookings テーブルで考える 93
会議室予約:どちらも「重なる予約は 0 件」を見て、同じ時間に予約を入れる 94
会議室予約:どちらも「重なる予約は 0 件」を見て、同じ時間に予約を入れる 95
会議室予約:どちらも「重なる予約は 0 件」を見て、同じ時間に予約を入れる 96
会議室予約:どちらも「重なる予約は 0 件」を見て、同じ時間に予約を入れる 97
会議室予約:どちらも「重なる予約は 0 件」を見て、同じ時間に予約を入れる 98
Write Skew のうち、ロックすべき行がまだ存在しないケース 99
Write Skew は Serializable だけが防ぐ 100
デフォルトの分離レベルでは、どのような問題が起こる? 101
今日のトーク 102
3. 並行性の問題を防ぐトランザクション設計手段 103
デフォルトの分離レベルで残る問題に、自分で対処する 104
Read Skew の対策:一貫したスナップショットで読むか、読む行を変更させない 105
Lost Update の対策:アトミックな更新・悲観ロック・楽観ロック 106
Write Skew の対策:ロックすべき行があるか、まだないか 107
Write Skew の対策:ロックすべき行があるか、まだないか 108
Write Skew の対策:ロックすべき行があるか、まだないか 109
Write Skew の対策:ロックすべき行があるか、まだないか 110
Write Skew の対策:ロックすべき行があるか、まだないか 111
部署の予算は、前提にした行を FOR UPDATE でロックすれば防げる 112
部署の予算は、前提にした行を FOR UPDATE でロックすれば防げる 113
部署の予算は、前提にした行を FOR UPDATE でロックすれば防げる 114
部署の予算は、前提にした行を FOR UPDATE でロックすれば防げる 115
部署の予算は、前提にした行を FOR UPDATE でロックすれば防げる 116
Write Skew の対策:ロックすべき行があるか、まだないか 117
ユーザー名の登録は users テーブルで考える 118
対策①:制約で書けるなら、DB に任せる(ユーザー名の UNIQUE) 119
対策①:制約で書けるなら、DB に任せる(ユーザー名の UNIQUE) 120
対策①:制約で書けるなら、DB に任せる(ユーザー名の UNIQUE) 121
対策①:制約で書けるなら、DB に任せる(ユーザー名の UNIQUE) 122
ロックするテーブルが存在しない例 123
ロックするテーブルが存在しない例 124
ロックするテーブルが存在しない例 125
ロックするテーブルが存在しない例 126
ロックするテーブルが存在しない例 127
対策④:「ない」を、ロックできる行に置き換える(競合の実体化) 128
対策④:「ない」を、ロックできる行に置き換える(競合の実体化) 129
対策④:「ない」を、ロックできる行に置き換える(競合の実体化)
対策④:「ない」を、ロックできる行に置き換える(競合の実体化) 131
対策④:「ない」を、ロックできる行に置き換える(競合の実体化) 132
実体化の対象は、例ごとに「必ずある行」を選ぶ 133
Write Skew の対策は、悲観ロック → Serializable → 競合の実体化 の順に検討する 134
今日のトーク 135
4. デッドロックとその対策 136
デッドロック:お互いが相手のロックを待ち続けて、どちらも進めない 137
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 138
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 139
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 140
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 141
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 142
デッドロックが起きるメカニズム:2 つの Tx が逆の順番で行をロックする 143
デッドロックは「起きにくくする」と「回復可能にする」の両方を設計する 144
回避①:ロックを取る順番をそろえる 145
回避①:ロックを取る順番をそろえる 146
回避①:ロックを取る順番をそろえる 147
回避①:ロックを取る順番をそろえる 148
回避①:ロックを取る順番をそろえる 149
回避①:ロックを取る順番をそろえる 150
回避②:Tx を短く保ち、ロックを持つ時間を減らす 151
回避③:インデックスで、ロックする行を絞る 152
余談: その他の回避方法 トランザクション分離レベルを下げるという手段もあるが、最終手段 https://kaigionrails.org/2026/talks/sho-work/ 153
余談: その他の回避方法 トランザクション分離レベルを下げるという手段もあるが、最終手段 後日登壇予定! https://kaigionrails.org/2026/talks/sho-work/ 154
回復:DB がデッドロックを検出した際の挙動 155
回復:デッドロックによって失敗した際のリトライの設計 156
回復:PHP(PDO)でリトライを書いた例 157
まとめ 158
並行性の問題が起こるトランザクションを設計する際の思考順序 159
並行性の問題が起こるトランザクションを設計する際の思考順序 160
並行性の問題が起こるトランザクションを設計する際の思考順序 161
並行性の問題が起こるトランザクションを設計する際の思考順序 162
並行性の問題を防げ! 実践トランザクション入門 Shoichi Ochi (@occhi) PHPカンファレンス愛媛2026 2026-10-03
Appendix - 参考資料 • • • • • • •
• • Designing Data-Intensive Applications(Martin Kleppmann, O'Reilly, 2017) ◦ https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/ データ指向アプリケーションデザイン(オライリー・ジャパン , 2019) ◦ https://www.oreilly.co.jp/books/9784873118703/ PostgreSQL: Transaction Isolation ◦ https://www.postgresql.org/docs/current/transaction-iso.html PostgreSQL: Explicit Locking ◦ https://www.postgresql.org/docs/current/explicit-locking.html PostgreSQL: Serialization Failure Handling ◦ https://www.postgresql.org/docs/current/mvcc-serialization-failure-handling.html MySQL 8.4: Transaction Isolation Levels ◦ https://dev.mysql.com/doc/refman/8.4/en/innodb-transaction-isolation-levels.html MySQL 8.4: InnoDB Locking ◦ https://dev.mysql.com/doc/refman/8.4/en/innodb-locking.html MySQL 8.4: Locking Reads ◦ https://dev.mysql.com/doc/refman/8.4/en/innodb-locking-reads.html MySQL 8.4: Deadlocks in InnoDB ◦ https://dev.mysql.com/doc/refman/8.4/en/innodb-deadlocks.html 164