2014-06-28 4 views
1

J'insère des enregistrements dans un couple de tables à savoir Dept et Emp. Si la table Dept est créée avec succès alors seulement je veux insérer des enregistrements dans la table Emp. En outre, si l'insertion de Emp échoue, je veux annuler toute la transaction qui inclut à la fois l'annulation de Emp ainsi que les tables Dept.Spring: Propagation.REQUIRED ne fonctionne pas

J'ai essayé en utilisant Propagation.REQUIRED comme indiqué ci-dessous:

Java Fichier

public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
    } 

} 

@Transactional(propagation=Propagation.REQUIRED) 
public void saveRecords(){ 
    saveDepartment(dept); 
    saveEmployee(empl);  
} 

context.xml

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> 

<bean id="transactionManager" 
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   
    <property name="dataSource" ref="dataSource" /> 
</bean> 

Problème:

Même si une insertion dans la table Emp échoue, l'insertion Dept devient persistante, ce que je ne veux pas. Je veux tout annuler.

Veuillez nous suggérer.

+1

Vous attrapez l'exception ... –

Répondre

4

Le problème est votre bloc catch. Étant donné que l'exception est interceptée, le tx n'est pas annulé.

Vous devez jeter l'exception:

public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
     throw e; 
    } 

} 

Et par ailleurs, la sémantique des Progation.Required signifie simplement: créer un nouveau tx si elle n'existe pas ou utiliser un existant s'il est tx en cours d'exécution.


Suite à votre commentaire ici est une suggestion pour voir l'effet de NEW tx:

@Transactional(propagation=Propagation.REQUIRES_NEW) 
public void saveEmployee(Employee empl){ 
    try { 
     jdbcTemplate.update("INSERT INTO EMP VALUES(?,?,?,?,?)",empl.getEmpId(),empl.getEmpName(), 
       empl.getDeptId(),empl.getAge(),empl.getSex()); 
    } catch (DataAccessException e) { 
     e.printStackTrace(); 
     throw e; 
    } 

} 

@Transactional(propagation=Propagation.REQUIRED) 
public void saveRecords(){ 
    saveDepartment(dept); 
    try{ 
     saveEmployee(empl); 
    }catch(Exception e){Logger.log("Fail to save emp !");}  
} 

Le point clé pour voir l'effet de REQUIRES_NEW est d'attraper l'exception autour saveEmployee. Si vous ne l'attrapez pas: l'exception se propagera dans l'autre tx (celle commencée lors de l'entrée de saveRecords()) et elle sera également restaurée.

+0

La solution ci-dessus a fonctionné. Juste à des fins de test, j'ai ajouté '@Transactional (propagation = Propagation.REQUIRES_NEW)' par-dessus la méthode 'saveEmployee' pour voir comment cela fonctionne. Mon attente était la suivante: l'enregistrement 'Dept' sera sauvegardé et l'enregistrement' Emp' ne sera pas sauvegardé car 'NEW' va créer une nouvelle transaction. Mais je suis surpris de voir la sortie: Ni l'enregistrement 'Dept' ni l'enregistrement' Emp' n'ont été sauvegardés. Ai-je manqué quelque chose? S'il vous plaît, expliquez. – user182944

+0

Pourquoi l'exception n'est-elle pas lancée dans ce cas? Est-ce parce que nous n'avons rien à annuler? Aussi, pourquoi mon code n'a pas fonctionné? Quelle différence fait le bloc try en invoquant la méthode 'saveEmployee'? S'il vous plaît avis – user182944

+0

@ user182944 voir mon édition éditée ;-) Avec cet exemple de code, je pense que vous verrez que le service sera sauvegardé même lorsque l'insertion d'insertion échouer – ben75

Questions connexes