2012-01-26 12 views
5

Ho una classe astratta e due sottoclassi che la estendono. Ho il seguente nella primavera del file di configurazionespring @ annotazione transazionale

<bean id="importConfigFile" class="xxx.ImportConfigFiles" parent="parentImportFile"></bean> 

<bean id="importFile" class="xxx.ImportUMTSKPIFiles" parent="parentImportFile"></bean> 

<bean id="parentImportFile" name="parentImportFile" class="xxx.ImportUMTSFiles" abstract="true"></bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

Nella mia classe astratta Ho i seguenti metodi

public void importDataToDB(){ 
    //all the good stuff goes in here 
} 

@Transactional 
public void executeInsertUpdateQuery(){ 
    //all the good stuff goes in here 
} 

Il mio codice Java

ImportConfigFiles importConfigFiles = (ImportConfigFiles)context.getBean("importConfigFile"); 
importConfigFiles.setFileLocation(destPath); 
importConfigFiles.importDataToDB(); 

questo non funziona. executeInsertUpdateQuery() esegue solo una query sql nativa. Se metto @Transactional su imortDataToDB() funziona, ma poi rende enorme la mia transazione dal momento che all'interno di quel metodo faccio un ciclo di tutte le righe in un file e inserisco i record in db.

risposta

8

Questa è una delle principali insidie ​​in primavera - se si chiama @Transactional -Metodo dal metodo non transazionale nella stessa classe, il @Transactional viene ignorato (a meno che non si utilizza AspectJ tessitura). Questo non è il problema di primavera di per sé - l'EJB presenta gli stessi difetti.

Purtroppo con i proxy-based classe di interfaccia-based e tutto si può fare è quello di dividere la classe in due:

public class BeanA() { 

    @Resource 
    private BeanB b; 

    public void importDataToDB(){ 
     b.executeInsertUpdateQuery(); 
    } 
} 

public class BeanB { 

    @Transactional 
    public void executeInsertUpdateQuery(){ 
     //all the good stuff goes in here 
    } 

} 

L'intero traffico è causato dalla implementazione interna delle deleghe AOP in primavera. Con il codice sopra la nuova transazione verrà avviata ogni volta che si chiama b.executeInsertUpdateQuery() da BeanA non transazionale.

Ho scritto sul mio blog Spring pitfalls: proxying, Spring AOP riddle e Spring AOP riddle demystified.

+0

Grazie per la risposta rapida. – user373201

0

Non proprio sicuro, quale sia la domanda, ma lo @Transactional avvolge l'intero metodo in una transazione, quindi ovviamente sarà enorme se si importa tutto in un unico metodo. Il vantaggio è che se in qualche luogo la tua importazione fallisce, l'intera transazione non verrà eseguita e nessun dato difettoso è presente nel tuo database.

Se non lo vuoi, dovrai gestire tu stesso le transazioni o chiamare un metodo annotato @Transactional per un sottoinsieme di dati, come stai facendo adesso per un'importazione, ma forse lo fai per 10 file o altro es restrizioni logiche.

Problemi correlati