Reputation: 11425
I have an abstract class and two sub classes that extend it. I have the following in spring config file
<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" />
In my abstract class I have the following methods
public void importDataToDB(){
//all the good stuff goes in here
}
@Transactional
public void executeInsertUpdateQuery(){
//all the good stuff goes in here
}
My java code
ImportConfigFiles importConfigFiles = (ImportConfigFiles)context.getBean("importConfigFile");
importConfigFiles.setFileLocation(destPath);
importConfigFiles.importDataToDB();
This does not work. executeInsertUpdateQuery() executes just one native sql query. If I put @Transactional on imortDataToDB() it works but then it makes my transaction huge since inside that method I loop through all the rows in a file and insert the records in db.
Upvotes: 5
Views: 1461
Reputation: 340693
This is one of the major pitfalls in Spring - if you call @Transactional
-method from non-transactional method in the same class, the @Transactional
is ignored (unless you use AspectJ weaving). This is not Spring problem per se - the EJB has the same shortcomings.
Unfortunately with interface-based and class-based proxies all you can do is to split your class in two:
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
}
}
The whole hustle is caused by the internal implementation of AOP proxies in Spring. With the code above new transaction will be started every time you call b.executeInsertUpdateQuery()
from non-transactional BeanA
.
I wrote about it on my blog Spring pitfalls: proxying, Spring AOP riddle and Spring AOP riddle demystified.
Upvotes: 8
Reputation: 10918
Not quite sure, what the question is, but @Transactional
wraps the entire method in one transaction so obviously it will be huge if you import everything in one method. The advantage is, that if at some place your import fails, the entire transaction will not get executed and no faulty data is in your database.
If you don't want that, you'll have to manage the transactions yourself or call a @Transactional
annotated method for a subset of your data, like you're doing right now for one import, but maybe you do it for 10 files or other e.g. logical restrictions.
Upvotes: 0