Come posso impedire agli inserti JPA di bloccare una tabella di database?
-
05-07-2019 - |
Domanda
Sto usando JPA supportato da Hibernate come livello di persistenza. Ho un processo multi-thread che aggrega i dati da una chiamata Soap e quindi memorizza una riga in un database. Il processo di solito finisce con l'inserimento di circa 700 righe e dura circa 1-3 ore, con le chiamate al sapone che rappresentano il principale collo di bottiglia.
Durante l'intero processo la tabella che inserisco in blocchi e non restituirà le istruzioni selezionate in modo tempestivo.
Ecco l'errore del server SQL:
Messaggio di errore: periodo di timeout della richiesta di blocco superato.
Come evitare di bloccare la tabella del mio database durante questo lungo processo?
Soluzione
Inserite tutte le 700 righe con la stessa transazione?
Dove si trova il limite della transazione? Se è possibile ridurre il limite della transazione, ovvero eseguire solo l'operazione di inserimento effettiva, in modo che il blocco venga bloccato.
Se è necessario che l'intero processo sia atomico, potrebbe essere un'idea per scriverlo in una tabella temporanea e quindi eseguire un inserimento in blocco (veloce) per inserirlo nella tabella principale.
Altri suggerimenti
Probabilmente dovrai cambiare il tuo livello di isolamento.
Ecco alcune informazioni: http://www.interview-questions-tips-forum.net/index.php/Your-Questions-on-Java/JDBC-Transaction/Transaction-Isolation-Levels
Parla dei diversi livelli di isolamento e di cosa possono aiutare a proteggersi. Il modo generale per farlo è iniziare con il rigoroso e poi abbassarlo se hai bisogno di tempi di risposta migliori, tenendo presente i requisiti di integrità dei dati / letture false.
modifica
I livelli delle Transazioni di primavera sono usati per astrarre i livelli di isolamento delle transazioni JDBC (o qualunque altra cosa) dal gestore delle transazioni. Sono definiti nella TransactionDefinition class e sono membri statici.
TransactionDefinition.ISOLATION_DEFAULT
Default isolation
TransactionDefinition.ISOLATION_READ_UNCOMMITTED
Lowest level of isolation; allows transactions to see uncommitted modifications from other transactions
TransactionDefinition.ISOLATION_READ_COMITTED
Cannot read uncommitted data
TransactionDefinition.ISOLATION_REPEATABLE_READ
Ensures repeatable reads
TransactionDefinition.ISOLATION_SERIALIZABLE
Most reliable; all transactions are executed atomically, and are treated as though they occurred serially.
Esistono anche livelli di propagazione delle transazioni. È possibile che si stia utilizzando una transazione per letture pure, che potrebbe essere eccessiva: le letture non richiedono transazioni, le scritture dovrebbero SEMPRE avere una transazione intorno a esse. I livelli di propagazione sono definiti anche in TransactionDefinition. Questi vengono utilizzati, di solito in un file di cablaggio a molla, per definire la serializzazione e la propagazione per una chiamata particolare. Se hai un esempio del tuo cablaggio, potrei essere in grado di dare qualche suggerimento / informazione in più.
Stai cercando di fare 700 richieste di sapone in una transazione JPA? Non farlo. : -)