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

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

B5ea40fde5be980a112c4ea58ad3bd39?s=47 ShoheiMitani
July 25, 2018
140

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

B5ea40fde5be980a112c4ea58ad3bd39?s=128

ShoheiMitani

July 25, 2018
Tweet

Transcript

  1. RailsͱDBͷτϥϯβΫγϣϯॲཧ  &CJTVSC

  2. ࡾ୩ণฏ Έͨʹ͠ΐ͏΁͍  ͠ΐʔ΁ʔ ָఱגࣜձࣾʢݩ'BCMJDʣ &OHJOFFS ɹ!TIPIFJ

  3. ࠓ೔ͷ࿩ w.Z42-ͷτϥϯβΫγϣϯʹ͍ͭͯ wόϦσʔγϣϯॲཧͱϩοΫͷམͱ݀͠

  4. എܠ w ೖۚγεςϜͰΤϥʔ͕ൃੜ w .ZTRM%VQMJDBUFFOUSZbʜ`GPSLFZbdJOEFY`*/4&35ʜ w ϩοΫ੍ޚ͕ߦΘΕ͍ͯΔՕॴ w ॏෳνΣοΫ΋ߦΘΕ͍ͯΔ w

    ͳͥʁʁʁ
  5. ֘౰ͷιʔείʔυʢΠϝʔδʣ 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
  6. ίʔυͷલʹ%#ͷ͓࿩ʜ

  7. .Z42-ͷඞਢ஌ࣝᶃɿ෼཭Ϩϕϧ • μʔςΟϦʔυ • ೋͭͷτϥϯβΫγϣϯ͕͋ͬͨͱ͖ʹɺยํͷະίϛοτͷσʔλ͕औಘͰ͖ Δ͜ͱ • ϑΝδʔϦʔυ • τϥϯβΫγϣϯ͕։࢝ͨ͠ޙʹଞ͕ߋ৽ɺ࡟আͯ͠ίϛοτͨ͠σʔλ͕औಘͰ

    ͖Δ͜ͱ • ϑΝϯτϜϦʔυ • ϑΝδʔϦʔυͷInsert൛ • ϩετΞοϓσʔτ • ଞͷτϥϯβΫγϣϯ͕ίϛοτ͢ΔલͷσʔλͰɺ৽͍͠σʔλΛॻ͖׵͑ͯ͠ ·͏͜ͱ τϥϯβΫγϣϯʹؔ܎͢Δ໰୊ʢଞʹ΋΋ͬͱ͋ΔΑʜʣ
  8. .Z42-ͷඞਢ஌ࣝᶃɿ෼཭Ϩϕϧ Լʹߦ͘΄ͲτϥϯβΫγϣϯ಺ͰͷσʔλͷҰ؏ੑ͕ߴ͍ ৄ͘͠͸͜͜ಡΜͰ https://dev.mysql.com/doc/refman/5.6/ja/glossary.html#glos_isolation_level .Z42-ʹ͓͚Δ෼཭ϨϕϧͱτϥϯβΫγϣϯ໰୊ͷ༧๷ঢ়گ

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

    …
 τϥϯβΫγϣϯ෼཭Ϩϕϧ͕ REPEATABLE READ (σϑΥϧτͷϨϕϧ) Ͱ͋Δ৔߹͸ɺ ಉ͡τϥϯβΫγϣϯ಺ͷ͢΂ͯͷҰ؏ੑಡΈऔΓͰɺͦͷτϥϯβΫγϣϯ಺ͷ࠷ॳͷ͜ ͷΑ͏ͳಡΈऔΓͰཱ֬͞Εͨεφοϓγϣοτ͕ಡΈऔΒΕ·͢ɻݱࡏͷτϥϯβΫγϣ ϯΛίϛοτͨ͋͠ͱʹɺ৽͍͠ΫΤϦʔΛൃߦ͢ΔͱɺΫΤϦʔͷ৽͍͠εφοϓγϣο τΛऔಘͰ͖·͢ɻ IUUQTEFWNZTRMDPNEPDSFGNBOKBJOOPECDPOTJTUFOUSFBEIUNM
  10. .Z42-ͷඞਢ஌ࣝᶄɿεφοϓγϣοτ উखͳΠϝʔδ εφοϓγϣοτ σʔλϕʔε BIGIN SELECT ~ SELECT ~ UPDATE

    ~ COMMIT ⁞   ⁠ ⁡
  11. վΊͯ֘౰ͷιʔείʔυ 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 ͍ͭͷεφοϓγϣοτʁ ͍ͭͷεφοϓγϣοτʁ
  12. ഉଞ੍ޚͱॏෳνΣοΫ εφοϓ γϣοτ σʔλϕʔε εφοϓ γϣοτ τϥϯβΫγϣϯ" τϥϯβΫγϣϯ# 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 ϩοΫղ์଴ͪ ⁞   ⁠ ⁡ ⁣ ⁢ ⁤ ⁥ ⁦ ➓ ੔߹ੑΛอͯͳ͍ͭͷ εφοϓγϣοτ͕ଘࡏ
  13. վΊͯ֘౰ͷιʔείʔυ 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 ผτϥϯβΫγϣϯͷ ίϛοτΛ൓өͰ͖ͯͳ͍
  14. ղܾࡦ w ࣮૷໘ w ϩοΫॲཧ͸τϥϯβΫγϣϯͷॳΊʹ࣮ߦ͢Δ w '0361%"5&͸ϩοΫղ์ޙʹ4&-&$5Λൃߦ͢Δ w "DUJWF3FDPSE#BTFUSBOTBDUJPOΑΓ "DUJWF3FDPSE-PDLJOH1FTTJNJTUJDXJUI@MPDLΛ࢖͏

    w ઃܭ໘ w ςʔϒϧΛ୯Ұ੹೚ʹ͢Δ w ςʔϒϧʹΞΫηε͢ΔϦΫΤετΛ੍ݶ͢Δ
  15. ·ͱΊ w .Z42-͸Ұ؏ੑಡΈऔΓʹΑΓϑΝϯτϜϦʔυΛ๷ࢭ͍ͯ͠Δ w ͦͷཪଆͰ͸εφοϓγϣοτ͕࡞੒͞Ε͍ͯΔ w τϥϯβΫγϣϯΛுΔ࣌͸ɺϩοΫͷҐஔʹؾΛ͚ͭΔ

  16. ͝੩ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠