Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transactional annotation on whole class + excluding a single method

I have a class with @Transactional annotation (instead of marking it for all of its method).

Although i have a single method inside that class that shouldn't be annotated as @Transactional.

My question is is there an annotation i can put in this method to mark it as "non-transactional"? or should i start marking each single method in this class as "transactional" excluding this method (a lot of work)

thanks.

like image 647
Urbanleg Avatar asked Aug 14 '13 13:08

Urbanleg


People also ask

Can @transactional annotation only be used at class level?

Annotation Type Transactional. Describes a transaction attribute on an individual method or on a class. When this annotation is declared at the class level, it applies as a default to all methods of the declaring class and its subclasses.

Is it sufficient to annotate the classes with the @transactional annotation?

It is not sufficient to tell you simply to annotate your classes with the @Transactional annotation, add the line ( <tx:annotation-driven/> ) to your configuration, and then expect you to understand how it all works.

Can we use @transactional on class?

The @Transactional annotation on the class level will be applied to every method in the class. However, when a method is annotated with @Transactional (like, updateFoo(Foo foo) ) this will take precedence over the transactional settings defined at the class level.

What happens if one @transactional annotated method is calling another @transactional annotated method on the same object instance?

1 Answer. Show activity on this post. If you call method2() from method1() within the same class, the @Transactional annotation of the second method will not have any effect because it is not called through proxy, but directly.


2 Answers

There are different transaction propagation strategies to use. These exist in the enum Propagation. The ones you might want to use are

/**  * Execute non-transactionally, suspend the current transaction if one exists.  * Analogous to EJB transaction attribute of the same name.  * <p>Note: Actual transaction suspension will not work on out-of-the-box  * on all transaction managers. This in particular applies to JtaTransactionManager,  * which requires the {@code javax.transaction.TransactionManager} to be  * made available it to it (which is server-specific in standard J2EE).  * @see org.springframework.transaction.jta.JtaTransactionManager#setTransactionManager  */ NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),  /**  * Execute non-transactionally, throw an exception if a transaction exists.  * Analogous to EJB transaction attribute of the same name.  */ NEVER(TransactionDefinition.PROPAGATION_NEVER), // maybe not this one 

So annotate the method inside your class with either of these.

@Transactional public class MyTransactionalClass {      @Transactional(propagation = Propagation.NOT_SUPPORTED)     public void nonTransactionalMethod() {...} } 

You can find all the propagation strategies here.

like image 146
Sotirios Delimanolis Avatar answered Oct 14 '22 10:10

Sotirios Delimanolis


Sorry to answer a six year old question, but I noticed the accepted answer doesn't actually answer the question. The question was how to have a method behave as though it was not annotated with @Transactional at all. Such a method will take part in a transaction if there is one, or execute non-transactionally if there is not. It will not suspend an existing transaction, or refuse to execute if there is one, one of which would be the result of the accepted answer.

The propagation to use is Propagation.SUPPORTS (in other words annotate the method with @Transactional(propagation = SUPPORTS). This will take part in the transaction if there is one, or execute non-transactionally if not, just like a non-annotated method would.

Not that according to the Javadoc it is not exactly the same as having no @Transactional annotation at all. It says:

Support a current transaction, execute non-transactionally if none exists. Analogous to EJB transaction attribute of the same name.

Note: For transaction managers with transaction synchronization, SUPPORTS is slightly different from no transaction at all, as it defines a transaction scope that synchronization will apply for. As a consequence, the same resources (JDBC Connection, Hibernate Session, etc) will be shared for the entire specified scope. Note that this depends on the actual synchronization configuration of the transaction manager.

The only way to have the method behave exacty as if it was not annotated with @Transactional at all is to do as OP suggests: don't annotate the class, but annotate all the other methods, but for most uses that will not be necessary and using Propagation.SUPPORTS will suffice.

like image 22
Pepijn Schmitz Avatar answered Oct 14 '22 08:10

Pepijn Schmitz