content: package com.bookstore;
  
  import com.bookstore.service.BookstoreService;
  import com.vladmihalcea.concurrent.aop.OptimisticConcurrencyControlAspect;
  
  import org.springframework.boot.ApplicationRunner;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.EnableAspectJAutoProxy;
  
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  import java.util.concurrent.TimeUnit;
  
  @SpringBootApplication
  @EnableAspectJAutoProxy
  public class MainApplication {
      private final BookstoreService bookstoreService;
  
      public MainApplication(BookstoreService bookstoreService) {
          this.bookstoreService = bookstoreService;
      }
  
      public static void main(String[] args) {
          SpringApplication.run(MainApplication.class, args);
      }
  
      @Bean
      public OptimisticConcurrencyControlAspect optimisticConcurrencyControlAspect() {
          return new OptimisticConcurrencyControlAspect();
      }
  
      @Bean
      public ApplicationRunner init() {
          return args -> {
              ExecutorService executor = Executors.newFixedThreadPool(2);
              executor.execute(bookstoreService);
              // Thread.sleep(2000); -> adding a sleep here will break the transactions concurrency
              executor.execute(bookstoreService);
  
              executor.shutdown();
              try {
                  executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
              } catch (InterruptedException ex) {
                  Thread.currentThread().interrupt();
              }
          };
      }
  }