Я настроил StaxEventItemWriter следующим образом:
@Bean
public StaxEventItemWriter fooWriter() {
return new StaxEventItemWriterBuilder()
.name("fooWriter")
.marshaller(marshaller())
.rootTagName("foos")
.build();
}
И MultiResourceItemWriter вот так:
@Bean
public MultiResourceItemWriter multiFooWriter() {
return new MultiResourceItemWriterBuilder()
.name("multiFooWriter")
.delegate(fooWriter())
.itemCountLimitPerResource(100)
.resourceSuffixCreator(index -> "-" + index + ".xml")
.resource(new FileSystemResource("foo"))
.build();
}
Однако, когда я запускаю пакет с использованием этих средств записи, я получаю следующее исключение:
Caused by: java.nio.channels.ClosedChannelException: null
at java.base/sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:160) ~[na:na]
at java.base/sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:284) ~[na:na]
at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.complete(TransactionAwareBufferedWriter.java:121) ~[spring-batch-infrastructure-5.2.4.jar:5.2.4]
at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.beforeCommit(TransactionAwareBufferedWriter.java:106) ~[spring-batch-infrastructure-5.2.4.jar:5.2.4]
... 44 common frames omitted
Я заметил, что это как-то связано с очисткой транзакций, поэтому я попробовал отключить транзакции в StaxEventItemWriter, и тогда это действительно сработало:
@Bean
public StaxEventItemWriter fooWriter() {
return new StaxEventItemWriterBuilder()
.name("fooWriter")
.marshaller(marshaller())
.rootTagName("foos")
.transactional(false) // Adding this works
.build();
}
Кроме того, если я записываю в один большой XML-файл (например, используя fooWriter() непосредственно в моей конфигурации Step вместо multiFooWriter()), то задание также завершается успешно.
Есть ли причина, по которой StaxEventItemWriter в сочетании с MultiResourceItemWriter не работает с транзакциями?
/>Для полноты примера, это класс Foo, который я использовал, и ItemReader (но это не имеет отношения к вопросу, поскольку проблема возникает с любым классом чтения/JAXB):
@Getter
@XmlRootElement(name = "foo")
@XmlType(propOrder = { "itemCount" })
@NoArgsConstructor
public class Foo implements ItemCountAware {
private int itemCount;
@Override
@XmlElement(name = "count")
public void setItemCount(int count) {
this.itemCount = count;
}
}
Для читателя я использую AbstractItemCountingItemStreamItemReader в сочетании с ItemCountAware для создания уникальных POJO Foo (но это не имеет отношения к проблеме):
@Component
public class FooReader extends AbstractItemCountingItemStreamItemReader {
public FooReader() {
setName("fooReader");
setMaxItemCount(10000);
}
@Override
protected Foo doRead() {
return new Foo();
}
@Override
protected void doOpen() {
}
@Override
protected void doClose() {
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... itemwriter