سؤال

@Override
    @Transactional(rollbackFor = { RuntimeException.class, Exception.class}, propagation = Propagation.REQUIRED)
    public String upload(ObjectVO vo) throws CustomException {
    .......
    }

In this service, I am inserting in to two tables. If there is an Exception while processing data (like mandatory field check) for the second table which supposed to get inserted after the first table, should it roll back the data inserted in the first table in the same transaction? In my case I am not getting it rolledback. What is the expected behaviour? (And yes, I am not catching the exception, its a custom exception which is included in rollbackFor clause, and is being thrown)
(I am using hibernate) The DAO Layer does getSession().save(entity); (getSession() returns currentSession)

(So the data in the first table remains)

The tables are not related.

<tx:annotation-driven/>

<bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
        lazy-init="true">
        <property name="dataSource" ref="dataSource" />
    </bean>
هل كانت مفيدة؟

المحلول

Are you sure the proxy actually apply on the method invocation ?

Assuming you use classic dynamic proxies (not aspectJ ones) can you ensure that the method is called from outside of its class ?

[edit] If you're using hibernate switch your transaction manager to HibernateTransactionManager

نصائح أخرى

First : As suggested , first enable the log by adding the following in your log4j

log4j.category.org.springframework=ALL

Second : if you are calling upload method from another method in the same Servcie class ( say xxxMethod) and the xxxMethod is not annotated by Transaction. then there wont be any rollback. because calls between the method to method in proxy is not handled by Spring context. thus it wont be able to wrap the transaction.

if the Second is not valid, please enable the log verify the log. your logs should show when the transaction starts and when it ends and what are methods are added to the transaction context.

Like below

DEBUG org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'saveDomain' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''


2014-04-04 10:25:24,276 [main] TRACE org.springframework.orm.jpa.JpaTransactionManager - Triggering beforeCompletion synchronization
2014-04-04 10:25:24,276 [main] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction rollback

And so

Note** , if you DAO Layer also annotated with Transaction and with propagation rule as Propagation.REQUIRES_NEW - the Dao method considered as individual UoW . So throwing exception from service layer would not rollback the previous transaction.

In general - it would be advise to keep the transaction in one layer and preferably with Service - Layer

I remember I also had such a problem. My problem was connected with a proper configuration. For instance: Did you specify in the TransactionManager declaration something like this:

transactionManager.setRollbackOnCommitFailure(true);

you may also use a debugger and catch the execution in your implementation of TransactionManager. You have there a method like rollback and you will see what is the reason that this operation is ommited.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top