2012-01-26 32 views
5

Tengo una clase abstracta y dos subclases que la amplían. Tengo el siguiente en el archivo de configuración de primaveraspring @ Anotación de Transactional

<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" /> 

En mi clase abstracta que tengo los siguientes métodos

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

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

Mi código java

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

esto no funciona. executeInsertUpdateQuery() ejecuta solo una consulta SQL nativa. Si pongo @Transactional en imortDataToDB() funciona, pero luego hace que mi transacción sea enorme, ya que dentro de ese método recorro todas las filas de un archivo e inserto los registros en db.

Respuesta

8

Ésta es una de las principales dificultades en la primavera - si se llama desde @Transactional -method método no transaccional en la misma clase, la @Transactional se ignora (a menos que utilice AspectJ tejido). Este no es el problema de Spring per se - el EJB tiene las mismas deficiencias.

desgracia con los proxies basados ​​en la clase basada en la interfaz y todo lo que puede hacer es dividir la clase en dos:

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 
    } 

} 

El conjunto ajetreo es causada por la implementación interna de poderes en la primavera de AOP. Con el código anterior, se iniciará una nueva transacción cada vez que llame al b.executeInsertUpdateQuery() desde BeanA no transaccional.

Escribí sobre ello en mi blog Spring pitfalls: proxying, Spring AOP riddle y Spring AOP riddle demystified.

+0

Gracias por la respuesta rápida. – user373201

0

No estoy seguro, cuál es la pregunta, pero @Transactional envuelve todo el método en una transacción, así que obviamente será enorme si importas todo en un método. La ventaja es que si en algún lugar falla su importación, no se ejecutará toda la transacción y no habrá datos defectuosos en su base de datos.

Si no quiere eso, tendrá que administrar las transacciones usted mismo o llamar a un @Transactional método anotado para un subconjunto de sus datos, como lo está haciendo ahora para una importación, pero tal vez lo haga para 10 archivos u otro, por ejemplo restricciones lógicas.

Cuestiones relacionadas