title: Spring UnexpectedRollbackException in nested @Transactional method
body: <p>I have a dao class (<code>MyDao</code>) which is marked with <code>@Transactional</code> annotaion (on class level) with no additional parameters. In this dao class I have a method which in some case needs to throw a checked exception and perform a transaction rollback. Something like this:</p>
  
  <pre><code>@Transactional
  public class MyDao {
  
      public void daoMethod() throws MyCheckedException() {
  
          if (somethingWrong) {
              TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
              throw new MyCheckedException("something wrong");
          }
  }
  </code></pre>
  
  <p>This works perfectly fine. However, this dao method is called from a service method, which is also marked as @Transactional:</p>
  
  <pre><code>public class MyService {
  
      @Autowired
      private MyDao myDao;
  
      @Transactional
      public void serviceMethod() throws MyCheckedException {
          myDao.daoMethod();
      }
  
  }
  </code></pre>
  
  <p>The problem is that when <code>daoMethod()</code> is called from <code>serviceMethod()</code> and marks the transaction as rollback only, I get an <code>UnexpectedRollbackException</code>.</p>
  
  <p>Under the hood, Spring creates two transactional interceptors: one for <code>MyDao</code> and one for <code>MyService</code>. When <code>daoMethod()</code> marks the transaction for rollback, the interceptor for <code>MyDao</code> performs the rollback and returns. But then the stack moves to the interceptor for <code>MyService</code>, which finds out about the previous rollback, and throws the <code>UnexpectedRollbackException</code>.</p>
  
  <p>One solution would be to remove the <code>@Transactional</code> annotation from MyDao. But this is not feasible right now because <code>MyDao</code> is used at a lot of places and this could cause errors.</p>
  
  <p>Another solution would be to not set the transaction as rollback only in <code>daoMethod()</code> but rather mark <code>serviceMethod()</code> to revert the transaction on <code>MyCheckedException</code>. But I don't like this solution because I have a lot of these "service methods" and I would have to mark all of them explicitly to rollback on that exception. Also everyone who would add a new service method in the future would have to think of this and therefore it creates opportunities for errors.</p>
  
  <p>Is there a way I could keep setting the transaction as rollback only from <code>daoMethod()</code> and prevent Spring from throwing the <code>UnexpectedRollbackException</code>? For instance, with some combination of parameters <code>isolation</code> and <code>propagation</code>?</p>