From 011dcb5be0434eef185a079fa905945fa6180794 Mon Sep 17 00:00:00 2001 From: erickson Date: Tue, 1 Feb 2011 23:40:24 +0000 Subject: [PATCH] make sure that inline overdue fines generation completes before we attempt to void overdues fines in checkin, otherwise it's possible to create multiple services (storage and cstore) competing for the same DB row mid-transaction, resulting in cstore timeouts and rollback of checkin. This could happen with backdated or amnesty checkins git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_2_0@19358 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- .../perlmods/OpenILS/Application/Circ/Circulate.pm | 44 +++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm index 1a75137d7a..b365acae7b 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Circulate.pm @@ -2220,7 +2220,6 @@ sub do_checkin { # run the fine generator against this circ, if this circ is there $self->generate_fines_start if $self->circ; - if( $self->checkin_check_holds_shelf() ) { $self->bail_on_events(OpenILS::Event->new('NO_CHANGE')); $self->hold($U->fetch_open_hold_by_copy($self->copy->id)); @@ -2316,6 +2315,8 @@ sub do_checkin { } if( $self->is_renewal ) { + $self->finish_fines_and_voiding; + return if $self->bail_out; $self->push_events(OpenILS::Event->new('SUCCESS')); return; } @@ -2425,8 +2426,7 @@ sub do_checkin { unless @{$self->events}; } - # gather any updates to the circ after fine generation, if there was a circ - $self->generate_fines_finish if ($self->circ); + $self->finish_fines_and_voiding; OpenILS::Utils::Penalty->calculate_penalties( $self->editor, $self->patron->id, $self->circ_lib) if $self->patron; @@ -2435,6 +2435,30 @@ sub do_checkin { return; } +sub finish_fines_and_voiding { + my $self = shift; + + # gather any updates to the circ after fine generation, if there was a circ + $self->generate_fines_finish if ($self->circ); + + return unless $self->backdate or $self->void_overdues; + + # void overdues after fine generation to prevent concurrent DB access to overdue billings + my $note = 'System: Amnesty Checkin' if $self->void_overdues; + + my $evt = OpenILS::Application::Circ::CircCommon->void_overdues( + $self->editor, $self->circ, $self->backdate, $note); + + return $self->bail_on_events($evt) if $evt; + + # make sure the circ isn't closed if we just voided some fines + $evt = OpenILS::Application::Circ::CircCommon->reopen_xact($self->editor, $self->circ->id); + return $self->bail_on_events($evt) if $evt; + + return undef; +} + + # if a deposit was payed for this item, push the event sub check_circ_deposit { my $self = shift; @@ -2946,12 +2970,6 @@ sub checkin_handle_circ { return $self->bail_on_events($evt) if $evt; } - if($self->void_overdues) { - my $evt = OpenILS::Application::Circ::CircCommon->void_overdues( - $self->editor, $circ, undef, 'System: Amnesty Checkin'); # TODO i18n for system-generated notes - return $self->bail_on_events($evt) if $evt; - } - if(!$circ->stop_fines) { $circ->stop_fines(OILS_STOP_FINES_CHECKIN); $circ->stop_fines(OILS_STOP_FINES_RENEW) if $self->is_renewal; @@ -3008,10 +3026,6 @@ sub checkin_handle_circ { return $self->bail_on_events($self->editor->event) unless $self->editor->update_action_circulation($circ); - # make sure the circ isn't closed if we just voided some fines - $evt = OpenILS::Application::Circ::CircCommon->reopen_xact($self->editor, $circ->id); - return $self->bail_on_events($evt) if $evt; - return undef; } @@ -3074,10 +3088,6 @@ sub checkin_handle_backdate { $bd = cleanse_ISO8601($new_date->ymd . 'T' . $original_date->strftime('%T%z')); $self->backdate($bd); - - my $evt = OpenILS::Application::Circ::CircCommon->void_overdues($self->editor, $self->circ, $bd); - return $evt if $evt; - return undef; } -- 2.11.0