2017-08-04 241 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配置。

相关问题