2017-09-26 42 views
1

J'ai un batch Java qui s'exécute sur plusieurs threads (généralement 16/32). Il y a une requête JDBC qui insère/met à jour de manière conditionnelle dans une table.java.sql.SQLException: ORA-00060: blocage détecté en attendant la ressource

Cependant, certains enregistrements échouent à cause d'erreur suivant:

[CobolThread 34] ERROR (com.splwg.base.support.sql.PreparedStatementImpl) Error executing update for rawSQL: 
update TABLE_A s set s.INT_COL = s.INT_COL + 1 where s.PRIM_ID = ? 
with 'string' parameter named 'primId' to : '8741104958' to indices: 1 
java.sql.SQLException: ORA-00060: deadlock detected while waiting for resource 

Dans cette requête, la colonne PRIM_ID est la colonne de clé primaire et il n'y a pas d'autres indices sur ce TABLE_A. J'ai parcouru de nombreux blogs disponibles autour de cela et tout ce qu'ils suggèrent est d'éviter l'utilisation de l'index Bitmap. Dans mon cas, il n'y a pas d'index bitmap ni de clé étrangère impliquée.

Remarque: Nous utilisions une instruction MERGE avant l'insertion/la mise à jour conditionnelle, mais elle échouait également pour la même raison.

S'il vous plaît aidez-moi à comprendre la cause de ce problème.

+0

Quelles sont les autres mises à jour que vous exécutez? Y a-t-il des mises à jour de tables contenant une référence de clé étrangère à PRIM_ID? Si c'est la seule mise à jour, êtes-vous certain que votre code multithread n'alloue pas le même ID à plus d'un thread? –

+0

@MickMnemonic, Il n'y a pas de référence FK à PRIM_ID. Un point supplémentaire que j'ai noté récemment était la présence d'attentes ITL sur cette table dans le rapport AWR. Je travaille sur l'optimisation des paramètres INITRANS et PCTFREE pour cela. Merci de votre aide. –

+0

Qu'en est-il du code de parallélisation, comment distribuez-vous 'PRIM_ID's entre les threads? –

Répondre

0

Des blocages apparaissent lorsque plusieurs commandes DML tentent d'accéder simultanément aux mêmes données.

Here et here vous pouvez trouver de courtes explications sur ce problème. C'est un comportement très commun d'une mauvaise commande SQL écrite. Je pense que vous devriez le réécrire.

+0

Merci, @HelenA pour votre réponse. Mais comme je l'ai mentionné, les commandes DML n'accèdent pas aux mêmes données. Prim_id est la clé unique utilisée dans la requête de mise à jour. Ainsi, plusieurs threads ne peuvent pas accéder simultanément aux mêmes données. –