0

I have read this @Transactional method called from another method doesn't obtain a transaction and learned that we can't call a @Transactional method from another method in the same class. I'm wondering if the following code works. I know that we can't put @Transactional on doSomething and have doSomethingTransactionally to call it directly, so I created a utility method that has @Transactional annotation in another class which takes in a function and execute it. The goal is to keep all the logic in the same class. If the following code does not work, is there a way to achieve this goal?

@Component
class A {

   @Autowired
   B b;

   public String doSomethingTransactionally() {
      return b.transactionalHelper(this::doSomething);
   }

   public String doSomething() {
      // a bunch of db operations
   }
}

@Component
class B {
   
   @Transactional
   public T transactionalHelper(Supplier<T> supplier) {
       return supplier.get();
   }
}
user3908406
  • 1,416
  • 1
  • 18
  • 32
  • where is your question? and no - this is not going to work. You need a spring managed entity if you want _any_ Spring annotation to work (`@Bean`, for example). Read about self injection. – Eugene Aug 29 '21 at 03:05
  • I didn't know you can't call a transactional method from the same class. I'm sure that it wasn't like that in earlier versions of Spring. – Jasper Blues Aug 29 '21 at 03:07
  • 1
    @JasperBlues you would be calling the proxy _directly_, without the wrapper that spring creates. – Eugene Aug 29 '21 at 03:08
  • @Eugene thanks for your response, I just updated my code, can you check again? I made both beans so they are within spring context – user3908406 Aug 29 '21 at 03:11
  • Ah yes of course. And from memory now - earlier versions of Spring *did* behave like this, depending on what kind of transaction interceptor was in use. The AOP weaver doesn't have this drawback. – Jasper Blues Aug 29 '21 at 03:50
  • Essentially, for advice to be applied, it has to cross the boundary of something that is managed by Spring. In this case, if you made a bean of some sort out of `a::doSomething`, _that_ would get advice applied, but not just `this::doSomething`. – chrylis -cautiouslyoptimistic- Aug 29 '21 at 04:16

0 Answers0