1
0
mirror of https://github.com/google/nomulus synced 2026-04-25 10:40:49 +00:00

Add handling for UpdateAutoTimestamp when not in a transaction (#1341)

* Add handling for UpdateAutoTimestamp when not in a transaction

It's not clear why this is sometimes causing test flakes, but getting better
logging involved should help clear it up.

This also changes AppEngineExtension to insert without reloading the initial
test data, rather than putting it (potentially involving a merge) and reloading
it in a separate transaction. This should hopefully reduce the chance of weird
conflicts.
This commit is contained in:
Ben McIlwain
2021-09-27 11:32:15 -04:00
committed by GitHub
parent f0b3be5bb6
commit ff3c848def
5 changed files with 37 additions and 12 deletions

View File

@@ -15,8 +15,12 @@
package google.registry.model;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.persistence.transaction.TransactionManagerFactory.ofyTm;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.flogger.FluentLogger;
import com.google.common.flogger.StackSize;
import com.googlecode.objectify.annotation.Ignore;
import com.googlecode.objectify.annotation.OnLoad;
import google.registry.model.translators.UpdateAutoTimestampTranslatorFactory;
@@ -40,6 +44,8 @@ import org.joda.time.DateTime;
@Embeddable
public class UpdateAutoTimestamp extends ImmutableObject {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
// When set to true, database converters/translators should do the auto update. When set to
// false, auto update should be suspended (this exists to allow us to preserve the original value
// during a replay).
@@ -57,7 +63,16 @@ public class UpdateAutoTimestamp extends ImmutableObject {
@PrePersist
@PreUpdate
void setTimestamp() {
if (autoUpdateEnabled() || lastUpdateTime == null) {
// On the off chance that this is called outside of a transaction, log it instead of failing
// with an exception from attempting to call jpaTm().getTransactionTime(), and then fall back
// to DateTime.now(UTC).
if (!jpaTm().inTransaction()) {
logger.atSevere().withStackTrace(StackSize.MEDIUM).log(
"Failed to update automatic timestamp because this wasn't called in a JPA transaction%s.",
ofyTm().inTransaction() ? " (but there is an open Ofy transaction)" : "");
timestamp = DateTime.now(UTC);
lastUpdateTime = DateTimeUtils.toZonedDateTime(timestamp);
} else if (autoUpdateEnabled() || lastUpdateTime == null) {
timestamp = jpaTm().getTransactionTime();
lastUpdateTime = DateTimeUtils.toZonedDateTime(timestamp);
}