title: How to disable transaction management in Spring Batch
body: <p>We are using spring batch to run our data processing steps. Inside every step we have the code which doesn't use transaction management. We are getting "java.sql.SQLException: Connection has already been closed." exceptions for our db operations when run in spring batch as it starts every step in a transaction. Can somebody suggest an approach on how to disable them.</p>
  
  <p>[EDIT]
  I am looking for an option like the one mentioned here <a href="http://forum.spring.io/forum/spring-projects/batch/91158-legacy-integration-tasklet-transaction" rel="nofollow noreferrer">http://forum.spring.io/forum/spring-projects/batch/91158-legacy-integration-tasklet-transaction</a>. This solution is not working in my case.</p>
  
  <p>[EDIT]
  I found a way to clear transactions in jdbc template, run my code and initialize them back. It is working for me. Is this a proper approach?</p>
  
  <pre><code>import org.springframework.batch.core.StepContribution;
  import org.springframework.batch.core.scope.context.ChunkContext;
  import org.springframework.batch.repeat.RepeatStatus;
  import org.springframework.transaction.support.TransactionSynchronization;
  import org.springframework.transaction.support.TransactionSynchronizationManager;
  
  import java.util.List;
  
  
  public class MyTasklet implements Tasklet {
  
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
  
      TransactionStatus transactionStatus = getTransactionSynchronizationsAndClear();
  
      try {
        /**
         * execute my code
         */
      } finally {
        initTransactionSyncs(transactionStatus);
      }
  
      return RepeatStatus.FINISHED;
    }
  
    private void initTransactionSyncs(TransactionStatus status) {
      try {
        TransactionSynchronizationManager.initSynchronization();
        TransactionSynchronizationManager.setCurrentTransactionName(status.getName());
        TransactionSynchronizationManager.setActualTransactionActive(status.isActive());
        TransactionSynchronizationManager.setCurrentTransactionReadOnly(status.isReadOnly());
        TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(status.getIsolationLevel());
        for (TransactionSynchronization sync : GainsightCollectionUtils.nullSafeList(status.getSyncs())) {
          TransactionSynchronizationManager.registerSynchronization(sync);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  
    private TransactionStatus getTransactionSynchronizationsAndClear() {
      try {
        TransactionStatus transactionStatus = new TransactionStatus();
        transactionStatus.setSyncs(TransactionSynchronizationManager.getSynchronizations());
        transactionStatus.setName(TransactionSynchronizationManager.getCurrentTransactionName());
        transactionStatus.setReadOnly(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
        transactionStatus.setIsolationLevel(TransactionSynchronizationManager.getCurrentTransactionIsolationLevel());
        transactionStatus.setActive(TransactionSynchronizationManager.isActualTransactionActive());
        TransactionSynchronizationManager.clear();
        return transactionStatus;
      } catch (Exception e) {
        e.printStackTrace();
      }
      return null;
    }
  
    private class TransactionStatus {
      private String name;
      private boolean readOnly;
      private boolean active;
      private Integer isolationLevel;
      private List&lt;TransactionSynchronization&gt; syncs;
  
      public String getName() {
        return name;
      }
  
      public void setName(String name) {
        this.name = name;
      }
  
      public boolean isReadOnly() {
        return readOnly;
      }
  
      public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
      }
  
      public boolean isActive() {
        return active;
      }
  
      public void setActive(boolean active) {
        this.active = active;
      }
  
      public Integer getIsolationLevel() {
        return isolationLevel;
      }
  
      public void setIsolationLevel(Integer isolationLevel) {
        this.isolationLevel = isolationLevel;
      }
  
      public List&lt;TransactionSynchronization&gt; getSyncs() {
        return syncs;
      }
  
      public void setSyncs(List&lt;TransactionSynchronization&gt; syncs) {
        this.syncs = syncs;
      }
    }
  }
  </code></pre>