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 9d3cbd07fd
commit eefb4c71aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

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());
}
});