Created
April 22, 2019 11:32
-
-
Save Irfy/5543b32efdb88777b61aa249f94894cc to your computer and use it in GitHub Desktop.
This file contains 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
Based on the pseudocode sample above, a `next/last/redo` could be executed on the second try, | |
without being executed in the first try, for *at least* the following reasons: | |
1. Initial transaction setup caused a retry with an unconditional `next/last/redo` in the body of the coderef | |
2. Some action in the coderef, before an unconditional `next/last/redo` caused a retry. | |
3. An unexpected or undesirable situation after a *skipped, conditional* `next/last/redo` causes a retry | |
(like optimistic locking failure). On the second try, conditions have changed (e.g. modification of data | |
in the database) and this changes the path taken by the code, triggering the *conditional* `next/last/redo`, | |
that wasn't triggered on the first try, due to different conditions in that run. |
This file contains 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
use strict; | |
use tx_exec qw(tx_exec); | |
for $customer_id (<>) { # manually supplied list of customer IDs | |
my ($tx_ret, $sub_ret) = tx_exec ("migrate_customer", sub { | |
# before we reach here, we will have created some transaction context, and already accessed the database | |
# so a retry can be triggered even before we enter our coderef | |
my ($tx) = @_; | |
my $customer = $tx->load_customer ($customer_id); # we could trigger a retry due to a timeout here | |
if (inconsistent_state($customer)) { | |
$logger->warn ("Inconsistent customer state, skipping"); | |
next; # inconspicuous `next`, attempting to skip to the next iteration of our local for-loop | |
} | |
# migrate the customer object to a different place/system, mark it as migrated in our database | |
}); | |
# upon exiting our sub, our tx_exec could detect a concurrent modification of data also modified by us, that started after | |
# our transaction and finished before it, necessitating a retry (classic optimistic locking). in the retry, we could | |
# end up in the inconsistent_state clause by chance, or a mistake elswhere in the system, even a temporary or incomplete | |
# manual modification in the database, that would make the customer object inconsistent according to some metrics. | |
} |
This file contains 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
use strict; | |
use warnings; | |
sub tx_exec { | |
# execute client code in the context of an application-level transaction | |
# things that can temporarily go wrong and cause a retry: | |
# * connectivity issues | |
# * lock timeout | |
# * concurrent modification (faster than us in optimistic locking) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment