diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java index c3c796ee1..db8bd0bce 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/file/FlatFileItemWriter.java @@ -16,6 +16,7 @@ package org.springframework.batch.item.file; +import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -59,6 +60,8 @@ import org.springframework.util.ClassUtils; public class FlatFileItemWriter extends ExecutionContextUserSupport implements ResourceAwareItemWriterItemStream, InitializingBean { + private static final boolean DEFAULT_TRANSACTIONAL = true; + protected static final Log logger = LogFactory.getLog(JdbcBatchItemWriter.class); private static final String DEFAULT_LINE_SEPARATOR = System.getProperty("line.separator"); @@ -86,6 +89,8 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement private FlatFileFooterCallback footerCallback; private String lineSeparator = DEFAULT_LINE_SEPARATOR; + + private boolean transactional = DEFAULT_TRANSACTIONAL; public FlatFileItemWriter() { setName(ClassUtils.getShortName(FlatFileItemWriter.class)); @@ -185,6 +190,14 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement this.footerCallback = footerCallback; } + /** + * Flag to indicate that writing to the buffer should be delayed if a + * transaction is active. Defaults to true. + */ + public void setTransactional(boolean transactional) { + this.transactional = transactional; + } + /** * Writes out a string followed by a "new line", where the format of the new * line separator is determined by the underlying operating system. If the @@ -375,7 +388,10 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement } outputBufferedWriter.flush(); - pos = fileChannel.position() + ((TransactionAwareBufferedWriter) outputBufferedWriter).getBufferSize(); + pos = fileChannel.position(); + if (transactional) { + pos += ((TransactionAwareBufferedWriter) outputBufferedWriter).getBufferSize(); + } return pos; @@ -500,9 +516,12 @@ public class FlatFileItemWriter extends ExecutionContextUserSupport implement */ private Writer getBufferedWriter(FileChannel fileChannel, String encoding) { try { - TransactionAwareBufferedWriter outputBufferedWriter = new TransactionAwareBufferedWriter(Channels - .newWriter(fileChannel, encoding), getName()); - return outputBufferedWriter; + Writer writer = Channels.newWriter(fileChannel, encoding); + if (transactional) { + return new TransactionAwareBufferedWriter(writer, getName()); + } else { + return new BufferedWriter(writer); + } } catch (UnsupportedCharsetException ucse) { throw new ItemStreamException("Bad encoding configuration for output file " + fileChannel, ucse); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java index ab013c4c1..67d3c4c8b 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/file/FlatFileItemWriterTests.java @@ -253,6 +253,38 @@ public class FlatFileItemWriterTests { } + @Test + public void testWriteStringTransactional() throws Exception { + writeStringTransactionCheck(null); + assertEquals(TEST_STRING, readLine()); + } + + @Test + public void testWriteStringNotTransactional() throws Exception { + writer.setTransactional(false); + writeStringTransactionCheck(TEST_STRING); + } + + private void writeStringTransactionCheck(final String expectedInTransaction) { + PlatformTransactionManager transactionManager = new ResourcelessTransactionManager(); + + writer.open(executionContext); + new TransactionTemplate(transactionManager).execute(new TransactionCallback() { + public Object doInTransaction(TransactionStatus status) { + try { + writer.write(Collections.singletonList(TEST_STRING)); + assertEquals(expectedInTransaction, readLine()); + } + catch (Exception e) { + throw new UnexpectedInputException("Could not write data", e); + } + + return null; + } + }); + writer.close(); + } + @Test public void testTransactionalRestart() throws Exception {