Make premium list saving run as a single transaction (#1480)

* Make premium list saving run as a single transaction

This fixes the bug where the new revision is saved, but then execution gets
halted for some reason (e.g. request timeout) before the entries finish saving,
which leaves the DB in a bad state with a new top revision containing zero
entries, thus making everything standard.
This commit is contained in:
Ben McIlwain 2021-12-30 12:53:39 -05:00 committed by GitHub
parent bfdea6fbe6
commit a6aa944c6c

View file

@ -19,6 +19,7 @@ import static google.registry.config.RegistryConfig.getDomainLabelListCacheDurat
import static google.registry.config.RegistryConfig.getSingletonCachePersistDuration;
import static google.registry.config.RegistryConfig.getStaticPremiumListMaxCachedEntries;
import static google.registry.persistence.transaction.TransactionManagerFactory.jpaTm;
import static google.registry.util.CollectionUtils.isNullOrEmpty;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
@ -156,24 +157,22 @@ public class PremiumListDao {
return save(PremiumListUtils.parseToPremiumList(name, currencyUnit, inputData));
}
/** Saves the given premium list (and its premium list entries) to Cloud SQL. */
public static PremiumList save(PremiumList premiumList) {
jpaTm().transact(() -> jpaTm().insert(premiumList));
premiumListCache.invalidate(premiumList.getName());
jpaTm()
.transact(
() -> {
if (premiumList.getLabelsToPrices() != null) {
Optional<PremiumList> savedPremiumList =
PremiumListDao.getLatestRevision(premiumList.getName());
jpaTm().insert(premiumList);
jpaTm().getEntityManager().flush(); // This populates the revisionId.
long revisionId = premiumList.getRevisionId();
if (!isNullOrEmpty(premiumList.getLabelsToPrices())) {
ImmutableSet.Builder<PremiumEntry> entries = new ImmutableSet.Builder<>();
premiumList.getLabelsToPrices().entrySet().stream()
.forEach(
entry ->
entries.add(
PremiumEntry.create(
savedPremiumList.get().getRevisionId(),
entry.getValue(),
entry.getKey())));
PremiumEntry.create(revisionId, entry.getValue(), entry.getKey())));
jpaTm().insertAll(entries.build());
}
});