diff -rupN module.orig/Reviews/src/Reviews/Listener/Review.php module/Reviews/src/Reviews/Listener/Review.php --- module.orig/Reviews/src/Reviews/Listener/Review.php 2016-07-27 09:08:47.000000000 +0000 +++ module/Reviews/src/Reviews/Listener/Review.php 2016-07-27 09:32:31.000000000 +0000 @@ -15,6 +15,7 @@ use Groups\Model\Group; use P4\Spec\Change; use P4\Spec\Exception\NotFoundException as SpecNotFoundException; use Projects\Model\Project; +use Record\Lock\Lock; use Reviews\Filter\GitInfo; use Reviews\Model\Review as ReviewModel; use Users\Model\User; @@ -128,6 +129,14 @@ class Review extends AbstractListenerAgg } } + // lock the next bit via our advisory locking to avoid potential race condition where another + // process tries to update a review from the same review id + $lock = new Lock(ReviewModel::LOCK_CHANGE_PREFIX . $id, $p4Admin); + $lock->lock(); + + try + { + $review->updateFromChange( $updateChange, isset($config['reviews']['unapprove_modified']) @@ -135,6 +144,16 @@ class Review extends AbstractListenerAgg : true ); + } catch (\Exception $e) { + // we handle this after unlocking + } + $lock->unlock(); + + // rethrow any errors we got when we were locked down + if (isset($e)) { + throw $e; + } + // ensure any new @mentions or @*mentions in the change description are added // we only count new @mentions to avoid resurrecting removed/un-required reviewers. $mentions = array_diff(Linkify::getCallouts($updateChange->getDescription()), $oldMentions);