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

RailsとDBのトランザクション処理

ShoheiMitani
July 25, 2018
280

 RailsとDBのトランザクション処理

ShoheiMitani

July 25, 2018
Tweet

More Decks by ShoheiMitani

Transcript

  1. ֘౰ͷιʔείʔυʢΠϝʔδʣ def index … ActiveRecord::Base.transaciton do order = Order.find(params[:order_id]) item

    = Item.lock.find(order.item_id) return … if payment_finished?(order, item) … Settlement.create(…) item.paid end end def payment_finished?(order, item) settlement = Settlement.find_by(order_id: order.id) settlement.present? && item.paid? end
  2. .Z42-ͷඞਢ஌ࣝᶃɿ෼཭Ϩϕϧ • μʔςΟϦʔυ • ೋͭͷτϥϯβΫγϣϯ͕͋ͬͨͱ͖ʹɺยํͷະίϛοτͷσʔλ͕औಘͰ͖ Δ͜ͱ • ϑΝδʔϦʔυ • τϥϯβΫγϣϯ͕։࢝ͨ͠ޙʹଞ͕ߋ৽ɺ࡟আͯ͠ίϛοτͨ͠σʔλ͕औಘͰ

    ͖Δ͜ͱ • ϑΝϯτϜϦʔυ • ϑΝδʔϦʔυͷInsert൛ • ϩετΞοϓσʔτ • ଞͷτϥϯβΫγϣϯ͕ίϛοτ͢ΔલͷσʔλͰɺ৽͍͠σʔλΛॻ͖׵͑ͯ͠ ·͏͜ͱ τϥϯβΫγϣϯʹؔ܎͢Δ໰୊ʢଞʹ΋΋ͬͱ͋ΔΑʜʣ
  3. .Z42-ͷඞਢ஌ࣝᶄɿεφοϓγϣοτ Ͳ͏΍ͬͯϑΝϯτϜϦʔυ͕ղܾ͞Ε͍ͯΔͷ͔ʁʁ 14.2.4 Ұ؏ੑඇϩοΫಡΈऔΓ Ұ؏ੑಡΈऔΓͱ͸ɺInnoDB ͕ϚϧνόʔδϣϯΛ࢖༻ͯ͠ɺ͋Δ࣌఺Ͱͷσʔλϕʔε ͷεφοϓγϣοτΛΫΤϦʔʹఏڙ͢Δ͜ͱΛҙຯ͠·͢ɻΫΤϦʔʹ͸ɺͦͷ࣌఺ΑΓ ΋લʹίϛοτ͞ΕͨτϥϯβΫγϣϯʹΑΔมߋͷΈ͕දࣔ͞Εɺͦͷ࣌఺ΑΓ΋͋ͱͷ τϥϯβΫγϣϯ·ͨ͸ίϛοτ͞Ε͍ͯͳ͍τϥϯβΫγϣϯʹΑΔมߋ͸දࣔ͞Ε·ͤ Μɻ

    …
 τϥϯβΫγϣϯ෼཭Ϩϕϧ͕ REPEATABLE READ (σϑΥϧτͷϨϕϧ) Ͱ͋Δ৔߹͸ɺ ಉ͡τϥϯβΫγϣϯ಺ͷ͢΂ͯͷҰ؏ੑಡΈऔΓͰɺͦͷτϥϯβΫγϣϯ಺ͷ࠷ॳͷ͜ ͷΑ͏ͳಡΈऔΓͰཱ֬͞Εͨεφοϓγϣοτ͕ಡΈऔΒΕ·͢ɻݱࡏͷτϥϯβΫγϣ ϯΛίϛοτͨ͋͠ͱʹɺ৽͍͠ΫΤϦʔΛൃߦ͢ΔͱɺΫΤϦʔͷ৽͍͠εφοϓγϣο τΛऔಘͰ͖·͢ɻ IUUQTEFWNZTRMDPNEPDSFGNBOKBJOOPECDPOTJTUFOUSFBEIUNM
  4. վΊͯ֘౰ͷιʔείʔυ def index … ActiveRecord::Base.transaciton do order = Order.find(params[:order_id]) item

    = Item.lock.find(order.item_id) return … if payment_finished?(order, item) … Settlement.create(…) item.paid end end def payment_finished?(order, item) settlement = Settlement.find_by(order_id: order.id) settlement.present? && item.paid? end ͍ͭͷεφοϓγϣοτʁ ͍ͭͷεφοϓγϣοτʁ
  5. ഉଞ੍ޚͱॏෳνΣοΫ εφοϓ γϣοτ σʔλϕʔε εφοϓ γϣοτ τϥϯβΫγϣϯ" τϥϯβΫγϣϯ# 4&-&$5 4&-&$5'0361%"5&

    */4&35 61%"5& $0..*5 4&-&$5 4&-&$5'0361%"5& */4&35 61%"5& $0..*5 4&-&$5 4&-&$5 ϩοΫղ์଴ͪ ⁞   ⁠ ⁡ ⁣ ⁢ ⁤ ⁥ ⁦ ➓ ੔߹ੑΛอͯͳ͍ͭͷ εφοϓγϣοτ͕ଘࡏ
  6. վΊͯ֘౰ͷιʔείʔυ def index … ActiveRecord::Base.transaciton do order = Order.find(params[:order_id]) item

    = Item.lock.find(order.item_id) return … if payment_finished?(order, item) … Settlement.create(…) item.paid end end def payment_finished?(order, item) settlement = Settlement.find_by(order_id: order.id) settlement.present? && item.paid? end ผτϥϯβΫγϣϯͷ ίϛοτΛ൓өͰ͖ͯͳ͍