sopehl
sopehl

Reputation: 1129

Why does not "@Transactional(propagation = propagation.NEVER)" work?

In the Spring docs, for NEVER propagation:

Execute non-transactionally, throw an exception if a transaction exists.

I wanted to try like following:

@Transactional(propagation = Propagation.NEVER)
public void getDeps(long ID) {
    System.out.println(databaseImp.getDepartmentByID(ID));
}

@Transactional(propagation = Propagation.REQUIRED)
public void allProcessOnDB_second(long ID) {
    getDeps(ID);
    operation(ID);
}

@Transactional
public void operation(long id){
    System.out.println(databaseImp.getDepartmentByID(id));
}

Well, it is not important what code wants to do.
I use the @Transactional(propagation = Propagation.NEVER) and I use this method in any transactional method but it doesn't work. I mean it must throw an exception, but it doesn't.

My Spring meta configuration file (XML) contains the following:

<context:annotation-config></context:annotation-config>
<context:component-scan base-package="database.transactionmanagement"/>

<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <constructor-arg name="dataSource" ref="datasource2"/>
</bean>

<bean id="datasource2" class="org.apache.tomcat.dbcp.dbcp2.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost/hr"/>
    <property name="username" value="root"/>
    <property name="password" value=""/>
</bean>

Thanks for your answers.

Upvotes: 4

Views: 4746

Answers (2)

JB Nizet
JB Nizet

Reputation: 691625

Spring transactions are proxy-based. That exception would be thrown if a bean A called another bean B, because the transactional aspect would intercept the call and throw the exception. But here, you're calling another method in the same object, and the transactional proxy is thus out of the picture.

Upvotes: 6

Predrag Maric
Predrag Maric

Reputation: 24403

@Transactional annotations only apply to the Spring proxy objects. For example, if you call allProcessOnDB_second() from some spring bean which injects your service like this

@Autowired 
private MyService myService; 
...
myService.allProcessOnDB_second();

then myService is Spring proxy, and its @Transactional(propagation = Propagation.REQUIRED) is applied. If you were to call myService.getDeps(id) then @Transactional(propagation = Propagation.NEVER) would be applied.

But when you call the first method, and then second method from it, then second method isn't called through Spring proxy but rather directly, so its transactional configuration is ignored.

Upvotes: 8

Related Questions