データ処理ステップを実行するためにスプリングバッチを使用しています。すべてのステップの中に、トランザクション管理を使用しないコードがあります。 「java.sql.SQLException:接続はすでに閉じられています。」というメッセージが表示されます。トランザクションのすべてのステップを開始するので、春バッチで実行されるときのdb操作の例外。誰かがそれらを無効にする方法に関する提案をすることができます。Springバッチでトランザクション管理を無効にする方法
[編集] ここに挙げたもののようなオプションを探しています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;
}
}
}
[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)のように聞こえます。あなたの問題は、トランザクションの管理方法に起因するものではなく、コードのどこかにバグがあるためです。トランザクション管理を無効にしようとするのは、必要な解決策ではない可能性があります。しかし、あなたのコードが何をしているかを知らなくても、実際の*問題を手助けすることはできません。 – Jesper
こんにちは@Jesper、私のDB接続プールの設定はremoveAbandonedTimeout = 600秒です。これは、自分のコードが接続を取得して10分以上保持すると、プールが終了することを意味します。通常、1回のDB操作は10分以上は持続しません。トランザクションが有効になると、トランザクションブロック(つまりバネ一歩ステップ)ですべてのDB操作を実行するために1つの接続のみが使用され、10分以上かかることになります。それが私が春のバッチでトランザクションを無効にしたい理由です –