select_for_updateについて
参考サイト
- http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html
- http://dev.mysql.com/doc/refman/5.1-olh/ja/innodb-locking-reads.html
- http://d.hatena.ne.jp/walf443/20130829/1377788440
サンプル
begin; select * from t_sample where id > 1 AND flg = 0 order by id asc limit1 for update; commit; # コミットするまでは、同一のレコードへ処理(select文を含む)をロックする
注意点
- トランザクションの効くストレージエンジン(innodb)でのみ有効
- for update をつけていないクエリはロックされない
- 同一のレコードへの処理をロックするため別条件で別レコードへの処理はロックされない
where id = 1
と
where id = 2
であればロックされない
where id > 1
と
where id = 2
であればロックされる
ActiveRecordでの利用方法
Sample.transaction do # select * from table where flg = 0 limit 1 for update @target = Sample.where("flg = 0 ").lock(true).first @target['flg'] = 1 @target.save end