Domanda

Ho un applicazione per la gestione delle vendite, magazzino e il pagamento su un magazzino intero saler da un'interfaccia web. In particolare, quando un ordine viene effettuato, si deve creare una linea corrispondente a ciascun prodotto ordinato con il rispettivo quantitativo. La validazione del disponibilità a magazzino è fatto al momento dell'ordine.

In considerazione dei seguenti due modi di convalida su ordinazione:

  1. Usa un BEFORE INSERT trigger sul OrderLine tavolo, che fa un SELECT sul Product verificando c'è abbastanza azione.

  2. Fare un SELECT ... FROM OrderLine JOIN Product WHERE quant < stock.

La mia domanda è: quale di queste due alternative è preferibile, e perché / per quello scenario

?
È stato utile?

Soluzione

Ho solo vederti fare un SELECT in entrambe le varianti. Se si vuole fare in modo di non vendere più di quello che hai in serbo (magazzino), è necessario diminuire il magazzino nella stessa transazione si inserisce l'ordine. In PostgreSQL 9.1 si può utilizzare un dati modificanti CTE per il lavoro:

WITH u AS (
   UPDATE product SET quant = quant - <put_order_quant_here>
   WHERE  product_id = <order_prod_id>
   AND    quant >= <put_order_quant_here>
   RETURNING product_id, <put_order_quant_here> AS quant
   )
INSERT INTO order_detail (order_id, product_id, quant)
SELECT <put_order_id_here>, product_id, quant
FROM   u;

l'aggiornamento nella CTE restituisce solo i valori se il prodotto ha scorte sufficienti. In questo caso, la quantità si riduce nella stessa transazione, poco prima del conferimento dell'incarico.

Mettere tutti i dettagli ordine in una sola operazione, se qualcuno di loro non riesce a inserire, ROLLBACK.


Possibili situazioni di stallo

Un altro consiglio: questo scenario potrebbe facilmente portare a situazioni di stallo. Dire, si hanno due ordini in arrivo allo stesso tempo, entrambi vogliono il prodotto A e B. Il primo comincia ordine mettendo l'order_detail su A, il secondo inizia con B. Poi le due operazioni di bloccare a vicenda. Ognuno di loro avrebbe aspettare l'altro per completare. Un stallo ne consegue.

In PostgreSQL una transazione verrà attendere per qualche tempo quando si è in stallo da serrature. A seconda dell'impostazione di deadlock_timeout (di default è 1s, che ho impostato almeno 5s sui server di produzione sereni), assegni per una possibile condizione di deadlock verrà eseguita.

Una volta rilevato, una transazione viene interrotta e segnalare un'eccezione situazione di stallo. L'altro può finire. Quale delle due è difficile da prevedere.

C'è un modo semplice per evitare questo tipo di situazioni di stallo: posizionare sempre il order_details in un ordine coerente . prodotti come ordine di product_id. In questo modo, lo scenario di cui sopra può mai accadere.

Altri suggerimenti

Aggiornamento:

Ho fatto questo post prima è stato aggiunto il tag di PostgreSQL, ma i concetti dovrebbe essere simile. Fondamentalmente è necessario essere in grado di bloccare il record in qualche modo per garantire che la quotazione in selezionata rimane il valore delle azioni si diminuisce. La stessa operazione che blocca il record dovrebbe aggiornare il brodo e inserimento nella tabella OrderLine. Non appena si stabilisce che le azioni non è disponibile rotolo tutta la schiena transazione.

Se questo trattamento viene fatto in un'operazione batch da un processo, allora non c'è bisogno di preoccuparsi di bloccaggio singoli record, ma è necessario assicurarsi che solo un processo batch può essere in esecuzione allo stesso tempo.


Se vuoi in ...

  1. WAIT del SELECT comunicato.
  2. BULK COLLECT del SELECT.
  3. FORALL .

Probabilmente anche vorrebbe per assicurare che tutte le voci avevano abbastanza azione, quindi si consiglia un po 'di aggregazione se lo stock è disponibile o meno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top