0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

#Rails + #MySQL / ApplicationRecord.transaction / begin rescue end / COMMIT or ROLLBACK / raise in Inner or outer Transaction / Ruby examples

Last updated at Posted at 2020-01-10
class User < ApplicationRecord
  validates_uniqueness_of :unique_id
end

I HOPE IT

def call_inner_transaction(id: , something_wrong: false)
  begin
    ActiveRecord::Base.transaction do
      StripeWebhookSucceededEvent.create!(unique_id: id)
      raise 'SOMETHING WRONG' if something_wrong
      puts '-' * 100
      puts 'EXECUTED!'
      puts '-' * 100
    end
  rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e
    puts '*' * 100
    puts "RAISED!"
    puts '*' * 100
    puts e.message
  end
end
dupulicated_id = rand(999_999_999_999)

# EXECUTE
# COMMIT 

SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s)
# [88] pry(main)> SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s)
#    (0.4ms)  BEGIN
#   StripeWebhookSucceededEvent Create (0.7ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('225043383392', '2020-01-09 10:53:13')
# ----------------------------------------------------------------------------------------------------
# EXECUTED!
# ----------------------------------------------------------------------------------------------------
#    (2.5ms)  COMMIT
# => nil

# DUPULICATE and RAISE
# NO EXECUTE
# ROLLBACK
SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s)
# [89] pry(main)> SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s)
#    (0.4ms)  BEGIN
#   StripeWebhookSucceededEvent Create (1.1ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('225043383392', '2020-01-09 10:53:17')
#    (2.6ms)  ROLLBACK
# ****************************************************************************************************
# RAISED!
# ****************************************************************************************************
# Mysql2::Error: Duplicate entry '225043383392' for key 'index_users_on_unique_id': INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('225043383392', '2020-01-09 10:53:17')
# => nil


# DUPULICATE and RAISE before SOMETHING WRONG
# NO EXECUTE
# ROLLBACK
SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s, something_wrong: true)
# [90] pry(main)> SomeClass.new.call_inner_transaction(id: dupulicated_id.to_s, something_wrong: true)
#    (0.4ms)  BEGIN
#   StripeWebhookSucceededEvent Create (2.6ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('225043383392', '2020-01-09 10:53:24')
#    (3.3ms)  ROLLBACK
# ****************************************************************************************************
# RAISED!
# ****************************************************************************************************
# Mysql2::Error: Duplicate entry '225043383392' for key 'index_users_on_unique_id': INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('225043383392', '2020-01-09 10:53:24')
# => nil

# SOMETHING WRONG
# NO DUPULICATE
# NO EXECUTE
# RAISE AND ROLLBACK
SomeClass.new.call_inner_transaction(id: rand(999_999_999_999).to_s, something_wrong: true)
# [91] pry(main)> SomeClass.new.call_inner_transaction(id: rand(999_999_999_999).to_s, something_wrong: true)
#    (0.9ms)  BEGIN
#   StripeWebhookSucceededEvent Create (1.0ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('357583484588', '2020-01-09 10:53:28')
#    (3.0ms)  ROLLBACK
# RuntimeError: SOMETHING WRONG
# from (pry):120:in `block in call_inner_transaction'

I DO NOT HOPE IT

def call_outer_transaction(id: , something_wrong: false)
  ActiveRecord::Base.transaction do
    begin
      StripeWebhookSucceededEvent.create!(unique_id: id)
      raise 'SOMETHING WRONG' if something_wrong
      puts '-' * 100
      puts 'EXECUTED!'
      puts '-' * 100
    rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique => e
      puts '*' * 100
      puts "RAISED!"
      puts '*' * 100
      puts e.message
    end
  end
end
dupulicated_id = rand(999_999_999_999)

# EXECUTE
# COMMIT
SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s)
# [93] pry(main)> SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s)
#    (0.4ms)  BEGIN
#   StripeWebhookSucceededEvent Create (0.6ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('64910455241', '2020-01-09 10:54:18')
# ----------------------------------------------------------------------------------------------------
# EXECUTED!
# ----------------------------------------------------------------------------------------------------
#    (4.7ms)  COMMIT
# => nil



# DUPLUCATED AND RAISED
# NO EXECUTE
# BUT COMMIT HAPPENS
SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s)
# [94] pry(main)> SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s)
#    (0.5ms)  BEGIN
#   StripeWebhookSucceededEvent Create (6.4ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('64910455241', '2020-01-09 10:54:26')
# ****************************************************************************************************
# RAISED!
# ****************************************************************************************************
# Mysql2::Error: Duplicate entry '64910455241' for key 'index_users_on_unique_id': INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('64910455241', '2020-01-09 10:54:26')
#    (5.4ms)  COMMIT
# => nil

# DUPLUCATED AND RAISED
# NO EXECUTE
# BUT COMMIT HAPPENS

SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s, something_wrong: true)
# [95] pry(main)> SomeClass.new.call_outer_transaction(id: dupulicated_id.to_s, something_wrong: true)
#    (1.0ms)  BEGIN
#   StripeWebhookSucceededEvent Create (1.3ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('64910455241', '2020-01-09 10:54:32')
# ****************************************************************************************************
# RAISED!
# ****************************************************************************************************
# Mysql2::Error: Duplicate entry '64910455241' for key 'index_users_on_unique_id': INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('64910455241', '2020-01-09 10:54:32')
#    (4.3ms)  COMMIT
# => nil

# SOMETHING WRONG
# NO DUPULICATE
# NO EXECUTE
# BUT RAISE AND ROLLBACK

SomeClass.new.call_outer_transaction(id: rand(999_999_999_999).to_s, something_wrong: true)
# [96] pry(main)> SomeClass.new.call_outer_transaction(id: rand(999_999_999_999).to_s, something_wrong: true)
#    (0.5ms)  BEGIN
#   StripeWebhookSucceededEvent Create (0.8ms)  INSERT INTO `users` (`unique_id`, `created_at`) VALUES ('710309047775', '2020-01-09 10:54:37')
#    (2.4ms)  ROLLBACK
# RuntimeError: SOMETHING WRONG
# from (pry):137:in `block in call_outer_transaction'

Original by Github issue

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

Twitter

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?