SlideShare una empresa de Scribd logo
1 de 29
MySQLで遭遇したトランザク
ションとロックのお話take2
小林拓
 トランザクション
 排他制御(ロック)
 楽観ロック
 悲観ロック
前提知識
 トランザクション処理は、既知の一貫した状態のデ
ータベースを維持するよう設計されており、相互依
存のある複数の操作が全て完了するか、全てキャン
セルされることを保証する。(Wikipediaより)
トランザクション
トランザクションの例
•G減少
•所持数増加
購入
トランザクションの例
•G減少
•所持数増加
購入
エラー
なかったこ
とにしたい!!
トランザクションの例
•G減少
•所持数増加
購入
セット
全て反映
⇒commit
全て元に戻す
⇒rollback
or
トランザクション実装
•SQL
BEGIN
~
COMMIT 又は ROLLBACK
•Rails
ActiveRecord::Base.transaction do
~
end
排他制御(ロック)
参考 : http://www.slideshare.net/kuromoyo/20140717-37115076
基本構成
DBサーバー
アプリケーショ
ンサーバー
悲観ロックと楽観ロック
楽観ロック
Rollback
悲観ロック
Id lock_version
1 0
楽観ロックの実装
•Railsの場合
usersテーブル
lock_versionというカラムを追加する
楽観ロックが適用されるとき
ActiveRecord::StaleObjectError というExceptionが発生して
Rollbackする
※楽観ロックの実装は本来処理上で手動で実装させるもの
楽観ロックある時とない時の違い
UPDATE `users` SET `money` = 4,
`updated_at` = '2015-02-25
11:07:28', `lock_version` = 3
WHERE (`users`.`id` = 2 AND
`users`.`lock_version` = 2)
楽観ロックがないときの
SQL
楽観ロックがあるときの
SQL
UPDATE `users` SET `money` =
4, `updated_at` = '2015-02-25
11:07:28’ WHERE (`users`.`id` = 2)
悲観ロックの実装
•Railsの場合
•SQL
BEGIN
SELECT `users` WHERE (`users`.`id` = 2) FOR UPDATE
…
COMMIT または ROLLBACK
user = User.find_by!(id: 2) (あらかじめインスタンスを取得しておく)
ActiveRecord::Base.transaction do
user.lock!
end
ロックをかけ忘れると
http://blogos.com/article/36121/
gree ドリランド 事件
↓記事
 READ UNCOMMITED
 READ COMMITED
 REPEATABLE READ
 SERIALLIZABLE
トランザクション分離レベル
<= Oracle, PostgreSQL, SQL Severのデフォルト
<= MySQLのデフォルト
参考: http://d.hatena.ne.jp/fat47/20140212/1392171784
下に行くほど不都合な読み込み現象が発生しなくなるが、
パフォーマンスが落ちる
Id money
1 400
例(Rails+MySQL)
User.transaction do
user = User.find_by(id: 1)
user.money += 400
user.save!
end
BEGIN;
SELECT * FROM users WHERE id = 1;
UPDATE users SET users.money = 800 WHERE id = 1;
COMMIT;
usersテーブル
SQLをだす
例リクエスト リクエスト
BEGIN;
SELECT * FROM users WHERE id = 1;
UPDATE users SET users.money = 800
WHERE id = 1;
COMMIT;
BEGIN;
SELECT * FROM users WHERE id = 1;
UPDATE users SET users.money = ? WHERE id =
1;
COMMIT
このとき、?に入る値はいくつ
でしょう?
ほぼ同時にリクエストが飛んできた。
このとき実行されたSQLは以下の通り
例について考察
 答えは800でした
 片方のトランザクションで既にcommitしてあるから、
SELECT * FROM users WHERE id = 1;これで取得できる値は
users.money = 800なはず。だから800 + 400 = 1200。よっ
て?の値は1200だ!!
READ UNCOMMITED
READ COMMITED
READ COMMITED
こうなると思ってました
REPEATABLE READ
こうなりました
教訓
必ずtransactionの外で一度select文を走らせ
てデータをとるようにしましょう!!
REPEATABLE READではトランザクション
が開始された時点で参照される値は同じ
になる
REPEATABLE READ
SERIALLIZABLE
複数トランザクションのSQLが入り混じら
ないように、強制的にトランザクションを
順序付けて処理します。
今まで出てきたすべての問題は発生しませ
んが、この分離レベルは読み取るすべての
行にロックをかけます。
ちなみに

Más contenido relacionado

Destacado

RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
nisobe58
 
ゆとりエンジニア交流会_20130706
ゆとりエンジニア交流会_20130706ゆとりエンジニア交流会_20130706
ゆとりエンジニア交流会_20130706
拓 小林
 
Ue4でandroidビルド ...できなかった...
Ue4でandroidビルド ...できなかった...Ue4でandroidビルド ...できなかった...
Ue4でandroidビルド ...できなかった...
拓 小林
 

Destacado (13)

こわくない同時実行制御
こわくない同時実行制御こわくない同時実行制御
こわくない同時実行制御
 
トランザクションをSerializableにする4つの方法
トランザクションをSerializableにする4つの方法トランザクションをSerializableにする4つの方法
トランザクションをSerializableにする4つの方法
 
RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
RDB入門 ~アプリケーション開発者が陥りやすいDB開発の落とし穴~
 
ABC2016Spring Androidアプリ実装アンチパターン(暫定)
ABC2016Spring Androidアプリ実装アンチパターン(暫定)ABC2016Spring Androidアプリ実装アンチパターン(暫定)
ABC2016Spring Androidアプリ実装アンチパターン(暫定)
 
ゆとりエンジニア交流会_20130706
ゆとりエンジニア交流会_20130706ゆとりエンジニア交流会_20130706
ゆとりエンジニア交流会_20130706
 
声貯
声貯声貯
声貯
 
バーチャルジャイアンツプレゼン
バーチャルジャイアンツプレゼンバーチャルジャイアンツプレゼン
バーチャルジャイアンツプレゼン
 
諸注意とご連絡
諸注意とご連絡諸注意とご連絡
諸注意とご連絡
 
Care farm
Care farmCare farm
Care farm
 
UE4よちよち勉強会オリエンテーション資料
UE4よちよち勉強会オリエンテーション資料UE4よちよち勉強会オリエンテーション資料
UE4よちよち勉強会オリエンテーション資料
 
My sqlで遭遇したトランザクションとロックのお話
My sqlで遭遇したトランザクションとロックのお話My sqlで遭遇したトランザクションとロックのお話
My sqlで遭遇したトランザクションとロックのお話
 
3d入門
3d入門3d入門
3d入門
 
Ue4でandroidビルド ...できなかった...
Ue4でandroidビルド ...できなかった...Ue4でandroidビルド ...できなかった...
Ue4でandroidビルド ...できなかった...
 

Último

Último (7)

Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 

My sqlで遭遇したトランザクションとロックのお話take2 2