title: Should I pass a managed entity to a method that requires a new transaction?
body: <p>My application loads a list of entities that should be processed. This happens in a class that uses a scheduler </p>
  
  <pre><code>@Component
  class TaskScheduler {
  
      @Autowired
      private TaskRepository taskRepository;
  
      @Autowired
      private HandlingService handlingService;
  
      @Scheduled(fixedRate = 15000)
      @Transactional
      public void triggerTransactionStatusChangeHandling() {
          taskRepository.findByStatus(Status.OPEN).stream()
                                 .forEach(handlingService::handle);
      }
  }
  </code></pre>
  
  <p>In my <code>HandlingService</code> processes each task in issolation using <code>REQUIRES_NEW</code> for propagation level.</p>
  
  <pre><code>@Component
  class HandlingService {
  
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      public void handle(Task task) {
          try {
              processTask(task); // here the actual processing would take place
              task.setStatus(Status.PROCCESED);
          } catch (RuntimeException e) {
              task.setStatus(Status.ERROR);
          }
      }
  }
  </code></pre>
  
  <p>The code works only because i started the parent transaction on <code>TaskScheduler</code> class. If i remove the <code>@Transactional</code> annotation the entities are not managed anymore and the update to the task entity is not propagated to the db.I don't find it natural to make the scheduled method transactional.</p>
  
  <p>From what i see i have two options:<br/></p>
  
  <p><strong>1. Keep code as it is today.</strong><br/></p>
  
  <ul>
  <li>Maybe it`s just me and this is a correct aproach. <br/> </li>
  <li>This varianthas the least trips to the database.</li>
  </ul>
  
  <p><strong>2. Remove the <code>@Transactional</code> annotation from the Scheduler, pass the id of the task and reload the task entity in the HandlingService.</strong><br/></p>
  
  <pre><code>@Component
  class HandlingService {
  
      @Autowired
      private TaskRepository taskRepository;
  
      @Transactional(propagation = Propagation.REQUIRES_NEW)
      public void handle(Long taskId) {
          Task task = taskRepository.findOne(taskId);
          try {
              processTask(task); // here the actual processing would take place
              task.setStatus(Status.PROCCESED);
          } catch (RuntimeException e) {
              task.setStatus(Status.ERROR);
          }
      }
  }
  </code></pre>
  
  <ul>
  <li>Has more trips to the database (one extra query/element)</li>
  <li>Can be executed using <code>@Async</code></li>
  </ul>
  
  <p>Can you please offer your opinion on which is the correct way of tackling this kind of problems, maybe with another method that i didn't know about?</p>