Reputation: 187
my application conatians hibernate and spring frameworks, on tamcat server and mysql.
i annotated a function as transactional, and i saw that it not behaves as transacitonal method (e.g i can see the changes in the DB in query browser, before the function finish).
the method is executed from a bean, but in different thread, like this:
executor.submit(new Runnable(){
@Override
public void run() {
someSpringService.doDbStuff();
}
});
inside doDbStuff, i am calling to several method, and each method using the template, like this:
return getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
return session.createCriteria(MyClass.class).add(Restrictions.eq("id", id))
.uniqueResult();
}
});
sometimes, i also exeuctue within the HiberateCallback native sql query, using the session i get as an argument to doInHiberate.
my questions are - 1. is the transactional annotation ignored because i am using different thread? 2. how can i execute the function that is annotated with transactional annotation as a spring bean (and not as a regular function - maybe it will solve 1 )? 3. if i create several HibernateCallback's within a callstack containing transactional annotation - is it behave as a transactional method? do i have to use the same session, and pass it between the inner functions?
thanks...
Upvotes: 1
Views: 823
Reputation: 24040
Make sure you have
<tx:annotation-driven/>
in your applicationContext.xml.
Upvotes: 0
Reputation: 340733
i can see the changes in the DB in query browser, before the function finish
When you run your method not from within a thread does it behave differently? This might be MySQL/transaction isolation issue...
- is the transactional annotation ignored because i am using different thread?
Not in this case. If you were creating a transaction in one thread and then spawning a new one, the latter would not "inherit" the transaction. In your case the transaction should start inside a new thread, behaving correctly.
Also try running this inside doDbStuff()
:
TransactionSynchronizationManager.isActualTransactionActive()
to make sure.
- how can i execute the function that is annotated with transactional annotation as a spring bean (and not as a regular function - maybe it will solve 1 )?
What do you mean? If you are calling someSpringService
was injected by Spring and doDbStuff()
is a public method annotated with @Transactional
- it should just work. There are a few gotchas, however for instance - if you are inside a bean calling public transactional method from private non-transactional one might not work.
- if i create several HibernateCallback's within a callstack containing transactional annotation - is it behave as a transactional method? do i have to use the same session, and pass it between the inner functions?
HibernateCallback
is clever enough to reuse the same JDBC connection -> Hibernate session -> transaction.
Upvotes: 1