Created
July 30, 2017 10:28
-
-
Save ericallam/368b0e96999b74d35abca4a0a98b06cb to your computer and use it in GitHub Desktop.
ApplicationService running a retryable REPEATABLE READ transaction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def call(form, attempts_count = 0, &block) | |
return block.call(form).unwrap unless transaction_handler.enabled? | |
return transaction_handler.transaction { block.call(form).unwrap } if nested_transaction_detector.call | |
if attempts_count < max_attempts | |
begin | |
attempts_count = attempts_count + 1 | |
transaction_handler.transaction(isolation: :repeatable_read) { block.call(form, attempt: attempts_count).unwrap } | |
rescue Survivor::Adapters::Error => error | |
if error.respond_to?(:cause) && error.cause.is_a?(ActiveRecord::StatementInvalid) && error.cause.cause.message.include?("could not serialize access due to concurrent update") | |
form.errors.clear | |
call(form, attempts_count, &block) | |
else | |
raise error | |
end | |
end | |
else | |
raise UncommittableRepeatableReadTransactionError.new(max_attempts) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def call(form) | |
repeatable_transaction(form) do |form, attempt: 1, outcome: Outcome.new| | |
capture { validate form } | |
.then { create_transfer form, outcome } | |
.then { activate_entry form, outcome } | |
.then { outcome.transfer } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment