Adios
BlogNext.js E-commerce

Next.js E-commerce

Come gestire scorte e invalidazione della cache in un negozio Next.js

Evita vendite superiori alle scorte con transazioni, prenotazioni, webhook idempotenti, tag di cache Next.js, invalidazione mirata e test di concorrenza.

Team di AdiosAggiornato 17 luglio 20268 min di lettura

Le scorte si gestiscono con una transazione, non con un valore in cache. La cache può mostrare ciò che era disponibile di recente; solo la scrittura nella fonte ufficiale può promettere l'ultima unità.

Definisci disponibile, riservato e venduto

Trail Supply ha due Alpine Shell blu di taglia media. onHand è il conteggio fisico, reserved indica le unità temporaneamente riservate da checkout attivi e sold quelle di ordini confermati. Available deriva da questi stati persistenti, anziché essere salvato come numero indipendente che può divergere.

Definisci quando inizia una prenotazione, quanto dura e quale evento la conferma o la libera. Riservare all'aggiunta al carrello è solitamente troppo presto; farlo a Checkout può essere adatto a scorte limitate; farlo al pagamento richiede una politica per acquirenti simultanei.

Rendi atomica la modifica delle scorte

Una sequenza di lettura e successiva scrittura permette a due richieste di vedere la stessa ultima unità. Usa una transazione del database, un lock di riga, un aggiornamento condizionale o un'altra operazione atomica supportata dall'archivio dati. La scrittura riesce solo se rimangono scorte non riservate sufficienti.

Imponi quantità non negative con vincoli del database dove possibile. Registra prenotazione, variante, quantità, proprietario o ordine in attesa, ora di creazione, scadenza e stato nella stessa transazione che modifica la disponibilità.

const reserved = await db.inventory.updateMany({
  where: {
    variantId,
    available: { gte: quantity },
  },
  data: {
    available: { decrement: quantity },
    reserved: { increment: quantity },
  },
});

if (reserved.count !== 1) {
  return { error: "Insufficient stock" };
}

Gestisci consapevolmente la scadenza delle prenotazioni

Salva una scadenza ed esegui un job di recupero programmato che liberi le prenotazioni attive la cui Checkout Session non può più completarsi. Rendi il rilascio idempotente: modificare una prenotazione già confermata o liberata non deve avere effetti.

Gli eventi tardivi richiedono una politica. Se il pagamento termina dopo la scadenza locale, riconcilia con lo stato del provider e dell'evasione, senza ricreare ciecamente le scorte o annullare un ordine pagato. Alcuni negozi accettano ordini arretrati, altri rimborsano. Codifica la decisione del prodotto.

Cache per le letture del catalogo, non per le decisioni sulle scorte

Con Cache Components abilitato, memorizza in cache la presentazione di prodotti e categorie usando use cache, un cacheLife adatto e tag per prodotto, variante e categorie interessate. La disponibilità mostrata può essere leggermente obsoleta solo se il checkout verifica i dati nella fonte ufficiale.

Tieni il codice di modifica di carrelli e scorte fuori dalle cache pubbliche condivise. I carrelli specifici dell'utente richiedono gestione per richiesta o cache privata. Non inserire mai una promessa di disponibilità legata a una sessione in una chiave che un altro acquirente può ricevere.

export async function getProduct(slug: string) {
  "use cache";
  cacheLife("minutes");
  cacheTag("product:" + slug);
  return loadProductView(slug);
}

Invalida il più piccolo insieme corretto

Dopo una modifica di scorte o prezzo, invalida il prodotto e ogni pagina di categoria che mostra il valore cambiato. updateTag permette all'utente di una Server Action di leggere subito la propria modifica; revalidateTag con un profilo appropriato è adatto a contenuti che possono restituire dati obsoleti durante l'aggiornamento.

Non svuotare la cache di tutte le pagine del negozio dopo una modifica a una giacca blu di taglia media. Un'invalidazione ampia aumenta il carico e rende meno comprensibile il comportamento della cache. Centralizza la costruzione dei tag, così pubblicazioni, webhook e azioni amministrative identificano le stesse voci.

Riconcilia eventi di magazzino e pagamento

Registra gli ID degli eventi esterni prima di applicare modifiche alle scorte. Rettifiche di magazzino, annullamenti, rimborsi e completamenti di pagamento possono ripetersi o arrivare in un ordine inatteso. Normalizza ciascuno in una transizione locale delle scorte e rifiuta transizioni incompatibili con lo stato corrente.

Mantieni un registro dei movimenti di sola aggiunta o una cronologia di audit sufficiente a spiegare il totale. Una quantità corrente senza cronologia delle prenotazioni e degli ordini è difficile da correggere dopo un guasto del provider o della distribuzione.

Verifica contesa e recupero sotto carico

Invia molte richieste simultanee di prenotazione per le ultime due unità e verifica che non ne riescano più di due. Interrompi un worker, ripeti un evento di pagamento, fai scadere una prenotazione, consegna un completamento tardivo e ricostruisci la vista del prodotto in cache. Verifica sia gli invarianti del database sia i risultati visibili al cliente.

Esegui quei test sulla compilazione di produzione in un'anteprima Adios. I log dell'ambiente di esecuzione mostrano contesa ed errori dei webhook, mentre database e dipendenze dai segreti restano espliciti nel manifest. Promuovi dopo il superamento della verifica dello stato e degli smoke test sulle scorte.

Tutti gli articoli