2017-08-04 243 views
-3

禁用事務管理我們正在使用Spring Batch的運行我們的數據處理步驟。在每一步中,我們都有不使用事務管理的代碼。我們得到「java.sql.SQLException:連接已經關閉。」我們的數據庫操作在Spring批處理中運行時的異常,因爲它啓動事務中的每一步。有人可以建議如何禁用它們的方法。如何在Spring Batch的

[編輯] 我正在尋找像這裏提到的選項http://forum.spring.io/forum/spring-projects/batch/91158-legacy-integration-tasklet-transaction。這種解決方案不適用於我的情況。

[編輯] 我找到了一種方法來清除JDBC模板交易,我的代碼運行並初始化回來。它爲我工作。這是一個合適的方法嗎?

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<TransactionSynchronization> 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<TransactionSynchronization> getSyncs() { 
     return syncs; 
    } 

    public void setSyncs(List<TransactionSynchronization> syncs) { 
     this.syncs = syncs; 
    } 
    } 
} 
+1

這聽起來像是一個[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。您的問題最有可能不是由於事務如何管理而導致的,而是因爲您的代碼中存在錯誤。試圖禁用事務管理很可能不是您需要的解決方案。但是,如果不知道代碼的作用,就無法幫助您處理* real *問題。 – Jesper

+0

嗨@Jesper,我的數據庫連接池設置有removeAbandonedTimeout = 600秒,這意味着,如果我的代碼獲取一個連接並保持超過10分鐘,池將其關閉。通常,我們的單個數據庫操作不會持續超過10分鐘。當交易僅啓用一個連接用於在一個事務塊運行我所有的數據庫操作(即春季批次步驟),它是要採取超過10分鐘。這就是我想在春季批次中禁用事務的原因 –

回答

0

而是禁止的交易,你必須啓用它們,因爲你將不能夠沒有交易與數據庫工作。您可以創建它們作爲通常的應用(連接到數據庫,打開的事務,關閉交易,關閉連接),但春天​​你可以用@Transactional註解做到這一點,或XML配置。

相關問題