2

I have service like this:

class ServiceImpl implements Service {
   @Override
   @Transactional
   public int method() {
      //some logic in transaction
      method2();//I want run this without transaction
      return 2;
   }

   @Override
   @Transactional(propagation = Propagation.REQUIRES_NEW)
   public void method2() {
     //external api call
   }
}

How can I run method2 without transaction or in new transaction? Can I run in my controller class this 2 method like this:

service.method();
service.method2();
grap
  • 45
  • 1
  • 9

1 Answers1

2

@Transactional is powered by Aspect-Oriented Programming. Therefore, processing occurs when a bean is called from another bean. You can resolve this problem by

  • self-inject
class ServiceImpl implements Service {

   @Lazy private final Service self;
   @Override
   @Transactional
   public int method() {
      //some logic in transaction
      self.method2();//I want run this without transaction
      return 2;
   }

   @Override
   @Transactional(propagation = Propagation.REQUIRES_NEW)
   public void method2() {
     //external api call
   }
}

  • create another bean.
class ServiceImpl implements Service {

   private final ExternalService service;
   @Override
   @Transactional
   public int method() {
      //some logic in transaction
      method2();//I want run this without transaction
      return 2;
   }

   @Override
   public void method2() {
     service.method2();
   }
}

@Service
class ExternalService{

   @Transactional(propagation = Propagation.REQUIRES_NEW)
   public void method2() {
     //external api call
   }
}
viking
  • 260
  • 2
  • 10
  • What if I call in controller method my transactional methods like this: service.method(); service.method2(); It will be One transaction? or two ? – grap Sep 23 '22 at 11:03
  • two different transaction – viking Sep 23 '22 at 11:16
  • So it could be also a solution? Since I have two proxies? – grap Sep 23 '22 at 11:27
  • Now I don't know what do you want to achieve. When you called `service.method()` invoked the method `method` will have a separate transaction. If you called `service.method2` also same situation – viking Sep 23 '22 at 11:44
  • But if I will invoke in method(){method2()} it will be one transaction? – grap Sep 23 '22 at 11:55
  • No, will be two, but you asked `How can I run method2 without transaction or in new transaction` so if you want disable transaction from method2 change propagation to NOT_SUPPORTED. You cannot achieve one transaction when both method are using separeted transactions by propagation REQUIRED and REQUIRES_NEW. – viking Sep 23 '22 at 12:24
  • when I call method2() in method() I have sonar issue on method2() : "@Transactional requirement is incompatible with the one for this method." It is okey ? in method2() i set @Transactional(propagation = Propagation.NOT_SUPPORTED) – grap Sep 23 '22 at 12:50
  • Try to organize your code by using another bean to manage transactions – viking Sep 23 '22 at 15:29