Don't auto-rebuild ChangeNotes from within BatchUpdate

BatchUpdate.ChangeTask#newChangeContext constructs a new ChangeNotes
from within an open transaction. If auto-rebuilding is enabled in this
path, then ChangeRebuilderImpl will call ChangeBundle#fromReviewDb,
which attempts to open another transaction. This is a somewhat
unintended use of gwtorm transactions in order to read a consistent
snapshot of the bundle. Transactions are not reentrant, so depending
on the backend this can cause a variety of failures, from failing fast
while trying to open the second transaction to
OrmConcurrencyExceptions when trying to commit the first transaction.

In an ideal world, there would be a gwtorm transaction-like thing to
do a consistent read across several entities that did not have the
same problem as a write transaction. That would be a lot of work. We
can work around the problem by simply disabling auto-rebuilding in the
BatchUpdate path.

When the change is stale, this results in the NoteDb write definitely
short-circuiting, as NoteDbUpdateManager with checkExpectedState will
refuse to apply an update if the change is out of date. This is fine:
the change is out of date to begin with, and it just stays out of date
after the next ReviewDb write. In the case of a BatchUpdate it
actually rebuilds itself nearly instantaneously during reindexing.
(This is also possibly a latency improvement if there are multiple
changes, since reindexing can happen in parallel threads.)

Change-Id: I1be7945c8917cf7522237505a38e0d4c86337650
This commit is contained in:
Dave Borowitz
2016-06-20 12:31:55 -04:00
parent ab598d6c8d
commit c697870e98
2 changed files with 72 additions and 1 deletions

View File

@@ -186,7 +186,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
}
public ChangeNotes createForBatchUpdate(Change change) throws OrmException {
return new ChangeNotes(args, change).load();
return new ChangeNotes(args, change, false, null).load();
}
// TODO(dborowitz): Remove when deleting index schemas <27.