简体   繁体   中英

transactions within spring beans

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 (eg 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...

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...

  1. 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.

  1. 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.

  1. 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.

Make sure you have

<tx:annotation-driven/>

in your applicationContext.xml.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM