The database can only hold 1 write concurrently and does not support transactions. If this value is exceeded, the database responds immediately with an error code XXXXX.
Questo è estremamente bizzarro per qualsiasi database moderno, ma accettiamo la premessa.
Ad un livello superiore, ci sono 2 approcci alle modifiche simultanee dei dati:
-
Pessimistico - Questo è basato sul blocco, che acquisisce un blocco su una risorsa prima di modificarlo e rilascia il blocco in seguito. Se un altro processo ha quella risorsa bloccata, le richieste per acquisire un blocco su quella stessa risorsa saranno block . Questo in pratica serializza gli aggiornamenti a questa risorsa. Sono intenzionalmente vago quando dico risorse, perché è piuttosto ambiguo. In modo semplicistico, una risorsa di solito è una riga in una tabella di database, ma può anche essere pagine / blocchi, intervalli o intere tabelle (le specifiche variano da un DBMS all'altro).
-
Ottimistico - I lock non vengono mai acquisiti, ma quando si aggiornano i dati, c'è una implicita it has it-not-changed-since-i-read-it e se la stipulazione è violata, verrà generato un errore. (A volte questo è implementato confrontando letteralmente vecchi valori con nuovi valori, o confrontando un codice hash, il numero di versione, ecc. I dettagli sono irrilevanti a questo livello).
Analisi del problema
Dato che si sta verificando un errore negli inserimenti simultanei, sospetto che tu abbia o meno l'ultimo, una strategia di concorrenza ottimistica in atto, o che tu abbia qualche DBW stupido che semplicemente non supporta gli aggiornamenti simultanei di sorta. Se si utilizza la concorrenza ottimistica, quindi, che è stata impostata, è un caso di utilizzo inadeguato. L'ottimista è, beh, ottimista. Si presuppone che gli aggiornamenti e le modifiche sovrapposte siano rari, quindi si ottimizza per il caso comune (lettura molto efficiente) a scapito di casi rari (modifiche in conflitto). Se si verifica un collo di bottiglia in cui gli inserimenti non funzionano regolarmente a causa di un caso del genere, il rapporto lettura-scrittura è più adatto al blocco pessimistico.
Breve storia, qualunque sia la ragione, la soluzione è la stessa: questi inserti devono essere serializzati. Alcune di queste risposte su questa domanda suggeriscono code di messaggi o dropping su un singolo server (il che, a proposito, non credo che risolverà davvero il problema ...), usando Hazelcast per fare serrature cross-server, ecc. sono tutte varianti della stessa identica cosa: serializza gli inserti!
Soluzione consigliata
Il fatto è che qualsiasi DBMS compatibile con ACID gestirà questo automaticamente per te. Se si sta utilizzando un DBMS compatibile con ACID, ma utilizzando la concorrenza ottimistica (una sorta di campo version
, probabilmente?), Si consiglia di farlo. Passa alla semplice insert
/ update
/ delete
senza alcuna versione e verifica se questo risolve il tuo problema.
Se non si utilizza un DBMS compatibile con ACID, la mia raccomandazione è di passare a un database migliore. Sì, puoi risolverlo con altri mezzi (come Hazelcast, coda di messaggi, ecc.), Ma aggiungono singoli punti di errore o reinventano il blocco del database. Francamente, questo mi spaventa. Il corretto blocco del database è un argomento estremamente complicato con gli eserciti di ingegneri che lo hanno progettato da PhD. Vorrei mai voler re-inventarlo da solo. Questo è uno spreco del mio tempo. Sarebbe più economico cambiare i database.
Oltre a
Per domande come questa, sarebbe bene specificare il software del database che stai usando. Sono scettico sul fatto che il tuo database abbia davvero questa limitazione. È come un'autostrada che consente solo un'auto alla volta.