title: Spring Optimistic Locking:How to retry transactional method till commit is successful
body: <p>I use Spring 2.5 and Hibernate JPA implementation with Java and "container" managed Transactions. </p>
  
  <p>I have a "after user commit" method that updates data in background and need to be committed regardless of <code>ConcurrencyFailureException</code> or <code>StaleObjectStateException</code> exception, because it will never be shown to client. In other words, need to make Optimistic Lock to Pessimistic. (Could happen if methods execution will take little bit longer and someone changed data in other transaction) </p>
  
  <hr>
  
  <p>I read a a lot about idempotent stuff, retry if exception in <a href="http://www.infoq.com/articles/Simplifying-Enterprise-Apps" rel="noreferrer">search for DEFAULT_MAX_RETRIES</a> or <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html" rel="noreferrer">6.2.7. Example</a> or <a href="http://www.springframework.net/doc-latest/reference/html/aop-aspect-library.html" rel="noreferrer">chapter 14.5. Retry</a>. I also found in stackoverflow <a href="https://stackoverflow.com/questions/2451260/how-to-configure-retryadvice-and-exceptiontranslation-for-deadlocks-using-nhibern">here</a> and <a href="http://www.springframework.net/doc-latest/reference/html/dao.html" rel="noreferrer">here</a>. </p>
  
  <p>I tried this:</p>
  
  <pre><code>public aspect RetryOnConcurrencyExceptionAspect {
  
      private static final int DEFAULT_MAX_RETRIES = 20;
      private int maxRetries = DEFAULT_MAX_RETRIES;
  
      Object around(): execution( * * (..) ) &amp;&amp; @annotation(RetryOnConcurrencyException) &amp;&amp; @annotation(Transactional) {
  
          int numAttempts = 0;
            RuntimeException failureException = null;
            do {
                  numAttempts++;
                  try {
                      return proceed(); 
                  } 
                  catch( OptimisticLockingFailureException ex ) {
                      failureException = ex;
                  }
                  catch(ConcurrencyFailureException ex) {
                      failureException = ex;
                  }
                  catch( StaleObjectStateException ex) {
                      failureException = ex;
                  }
            } while( numAttempts &lt;= this.maxRetries );
            throw failureException;
  
      }
  }
  </code></pre>
  
  <p><code>RetryOnConcurrencyException</code> is my Annotation to mark methods that need to be retried, if a exception occurrs. Didn't work... I also tried several ways like <code>SELECT ... FOR UPDATE</code>, <code>EntityManager.lock(...)</code></p>
  
  <p>What is the best way to avoid stale data, dirty reads etc. such a strategy with Spring? Retry?, synchronized?, JPA lock?, isolation?, select ... for update? I could not get it to work and I really happy about any help.</p>
  
  <hr>
  
  <p>Here is some pseudo code what I like to do:</p>
  
  <pre><code>void doSomething(itemId) {
      select something into A;
      select anotherthing into B;
  
      // XXX
      item = getItemFormDB( itemId ); // takes long for one user and for other concurrent user it could take less time
      item.setA(A);
      item.setB(B);
  
      // YYYY
      update item; 
  }
  </code></pre>
  
  <p>Between // XXX and // YYY another session could modify the item, then the StaleObjectStateException gets thrown.</p>