2010-09-06 5 views
0

J'ai deux applications Java: l'une d'entre elles insère des enregistrements dans Table1. La deuxième application lit les N premiers éléments et les supprime. Lorsque la 1ère application insère des données intensives, la 2ème échoue lorsque j'essaie de supprimer des lignes avec CannotSerializeTransactionException. Je ne vois aucun problème: les éléments insérés sont visibles dans select/delete uniquement lorsque la transaction d'insertion est terminée. Comment puis-je le réparer? Merci.Les suppressions de base de données ont échoué pendant les insertions

TransactionTemplate tt = new TransactionTemplate(platformTransactionManager); 
    tt.setIsolationLevel(Connection.TRANSACTION_SERIALIZABLE); 
    tt.execute(new TransactionCallbackWithoutResult() {     
    @Override 
    protected void doInTransactionWithoutResult(TransactionStatus status) { 
     List<Record> records = getRecords(); // jdbc select 
     if (!records.isEmpty()) { 
      try { 
       processRecords(records); // no database 
       removeRecords(records); // jdbc delete - exception here 
      } catch (CannotSerializeTransactionException e) { 
       log.info("Transaction rollback"); 
      } 
     } else { 
      pauseProcessing(); 
      } 
     } 
    }); 

pauseProcessing() - sommeil

public void removeRecords(int changeId) { String sql = "delete from RECORDS where ID <= ?"; 
     getJdbcTemplate().update(sql, new Object[]{changeId});} 
+2

vous devrez probablement montrer quel code vous utilisez pour aider les gens –

+0

Comment contrôler les transactions? Vos deux applications fonctionnent-elles dans le même conteneur? – rsilva4

+0

Non, les applications sont séparées: d'abord le service web basé sur Tomcat et le second est le fonctionnement autonome de Java sur un autre serveur. – alex543

Répondre

1

Utilisez-vous Connection.TRANSACTION_SERIALIZABLE aussi dans la première application? Ressemble à la première table de verrous d'application, donc la seconde ne peut pas y accéder (impossible de démarrer la transaction). Peut-être que Connection.TRANSACTION_REPEATABLE_READ pourrait être suffisant?

Probablement vous pouvez également configurer la deuxième application pour ne pas lever l'exception quand elle ne peut pas accéder aux ressources, mais pour l'attendre.

0

Cela semble indiquer que vous lisez des données non validées. Êtes-vous sûr de bien paramétrer le niveau d'isolement?

Il me semble que vous mélangez des constantes de deux classes différentes: Ne devriez-vous pas passer TransactionDefinition.ISOLATION_SERIALIZABLE au lieu de Connection.TRANSACTION_SERIALIZABLE à la méthode setIsolationLevel? Pourquoi avez-vous défini le niveau d'isolation de toute façon? Le niveau d'isolation par défaut d'Oracle (read committed) est généralement le meilleur compromis entre cohérence et rapidité et devrait parfaitement fonctionner dans votre cas.

+1

Dans Oracle, une session ne peut jamais lire les données non validées d'une autre session. –

Questions connexes