BATCH-7: Remove transaction synchronization and state management from input/output sources (formerly buffering)
http://jira.springframework.org/browse/BATCH-7 Use StreamManager to start/end transaction in step executor
This commit is contained in:
@@ -12,9 +12,7 @@ import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.stream.GenericStreamContext;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
public class DrivingQueryItemReaderTests extends TestCase {
|
||||
@@ -150,15 +148,11 @@ public class DrivingQueryItemReaderTests extends TestCase {
|
||||
|
||||
|
||||
private void commit() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_COMMITTED);
|
||||
((ItemStream) source).mark(null);
|
||||
}
|
||||
|
||||
private void rollback() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
((ItemStream) source).reset(null);
|
||||
}
|
||||
|
||||
private InitializingBean getAsInitializingBean(ItemReader source) {
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultFlatFileItemReader}
|
||||
@@ -98,13 +97,13 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
|
||||
inputSource.read(); // #1
|
||||
inputSource.read(); // #2
|
||||
// commit them
|
||||
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
inputSource.mark(null);
|
||||
// read next record
|
||||
inputSource.read(); // # 3
|
||||
// mark record as skipped
|
||||
inputSource.skip();
|
||||
// read next records
|
||||
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
inputSource.reset(null);
|
||||
|
||||
// we should now process all records after first commit point, that are
|
||||
// not marked as skipped
|
||||
@@ -136,7 +135,7 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
|
||||
// mark record as skipped
|
||||
inputSource.skip();
|
||||
// rollback
|
||||
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
inputSource.reset(null);
|
||||
// read next record
|
||||
inputSource.read(); // should be #1
|
||||
|
||||
@@ -146,33 +145,6 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test skip and skipRollback functionality
|
||||
* @throws IOException
|
||||
*/
|
||||
public void testTransactionSynchronizationUnknown() throws Exception {
|
||||
|
||||
inputSource.close();
|
||||
inputSource.setResource(getInputResource("testLine1\ntestLine2\ntestLine3\ntestLine4\ntestLine5\ntestLine6"));
|
||||
inputSource.open();
|
||||
|
||||
// read some records
|
||||
inputSource.read();
|
||||
inputSource.skip();
|
||||
inputSource.read();
|
||||
|
||||
StreamContext statistics = inputSource.getStreamContext();
|
||||
long skipped = statistics.getLong(DefaultFlatFileItemReader.SKIPPED_STATISTICS_NAME);
|
||||
long read = statistics.getLong(DefaultFlatFileItemReader.READ_STATISTICS_NAME);
|
||||
|
||||
// call unknown, which has no influence and therefore statistics should
|
||||
// be the same
|
||||
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_UNKNOWN);
|
||||
statistics = inputSource.getStreamContext();;
|
||||
assertEquals(skipped, statistics.getLong(DefaultFlatFileItemReader.SKIPPED_STATISTICS_NAME));
|
||||
assertEquals(read, statistics.getLong(DefaultFlatFileItemReader.READ_STATISTICS_NAME));
|
||||
}
|
||||
|
||||
public void testRestartFromNullData() throws Exception {
|
||||
inputSource.restoreFrom(null);
|
||||
assertEquals("[FlatFileInputTemplate-TestData]", inputSource.read().toString());
|
||||
@@ -201,7 +173,7 @@ public class DefaultFlatFileItemReaderTests extends TestCase {
|
||||
inputSource.read();
|
||||
inputSource.read();
|
||||
// commit them
|
||||
inputSource.getTransactionSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
inputSource.mark(null);
|
||||
// read next two records
|
||||
inputSource.read();
|
||||
inputSource.read();
|
||||
|
||||
@@ -24,12 +24,11 @@ import java.util.Collections;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.batch.item.writer.ItemTransformer;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
|
||||
/**
|
||||
* Tests of regular usage for {@link FlatFileItemWriter} Exception cases will be
|
||||
@@ -286,15 +285,6 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
assertEquals("testLine1", lineFromFile);
|
||||
}
|
||||
|
||||
public void testUnknown() throws Exception {
|
||||
inputSource.write("testLine1");
|
||||
// rollback
|
||||
unknown();
|
||||
inputSource.close();
|
||||
String lineFromFile = readLine();
|
||||
assertEquals("testLine1", lineFromFile);
|
||||
}
|
||||
|
||||
public void testRestart() throws Exception {
|
||||
|
||||
// write some lines
|
||||
@@ -380,17 +370,11 @@ public class FlatFileItemWriterTests extends TestCase {
|
||||
}
|
||||
|
||||
private void commit() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_COMMITTED);
|
||||
((ItemStream) inputSource).mark(null);
|
||||
}
|
||||
|
||||
private void rollback() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
((ItemStream) inputSource).reset(null);
|
||||
}
|
||||
|
||||
private void unknown() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,6 @@ import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationMan
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -159,15 +156,11 @@ public abstract class AbstractJdbcItemReaderIntegrationTests extends AbstractTra
|
||||
|
||||
|
||||
private void commit() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_COMMITTED);
|
||||
((ItemStream) source).mark(null);
|
||||
}
|
||||
|
||||
private void rollback() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
((ItemStream) source).reset(null);
|
||||
}
|
||||
|
||||
private ItemStream getAsRestartable(ItemReader source) {
|
||||
|
||||
@@ -12,9 +12,6 @@ import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationMan
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -230,15 +227,11 @@ public abstract class AbstractDataSourceItemReaderIntegrationTests extends Abstr
|
||||
}
|
||||
|
||||
private void commit() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_COMMITTED);
|
||||
((ItemStream) source).mark(((ItemStream) source).getStreamContext());
|
||||
}
|
||||
|
||||
private void rollback() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
((ItemStream) source).reset(((ItemStream) source).getStreamContext());
|
||||
}
|
||||
|
||||
private Skippable getAsSkippable(ItemReader source) {
|
||||
|
||||
@@ -16,14 +16,10 @@
|
||||
|
||||
package org.springframework.batch.io.support;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.StreamContext;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -44,60 +40,18 @@ public class AbstractTransactionalIoSourceTests extends TestCase {
|
||||
TransactionSynchronizationManager.initSynchronization();
|
||||
}
|
||||
|
||||
//AbstractItemReader should synchronize on first call to read.
|
||||
public void testSynchronizationRegistration(){
|
||||
|
||||
source.registerSynchronization();
|
||||
|
||||
List synchronizations = (List)TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchronizations.size());
|
||||
}
|
||||
|
||||
public void testCommit(){
|
||||
|
||||
source.registerSynchronization();
|
||||
commit();
|
||||
|
||||
source.mark(null);
|
||||
assertTrue(source.commitCalled);
|
||||
assertFalse(source.rollbackCalled);
|
||||
}
|
||||
|
||||
public void testRollback(){
|
||||
|
||||
source.registerSynchronization();
|
||||
|
||||
rollback();
|
||||
|
||||
source.reset(null);
|
||||
assertFalse(source.commitCalled);
|
||||
assertTrue(source.rollbackCalled);
|
||||
}
|
||||
|
||||
public void testCommitUnsynchronizedSource(){
|
||||
|
||||
commit();
|
||||
|
||||
assertFalse(source.commitCalled);
|
||||
assertFalse(source.rollbackCalled);
|
||||
}
|
||||
|
||||
public void testMultipleSynchronizations(){
|
||||
|
||||
source.registerSynchronization();
|
||||
source.registerSynchronization();
|
||||
|
||||
//multiple calls to read should result in only one synchronization
|
||||
List synchronizations = (List)TransactionSynchronizationManager.getSynchronizations();
|
||||
assertEquals(1, synchronizations.size());
|
||||
}
|
||||
|
||||
public void testUnknownStatus(){
|
||||
|
||||
invokeUnknown();
|
||||
|
||||
assertFalse(source.commitCalled);
|
||||
assertFalse(source.rollbackCalled);
|
||||
}
|
||||
|
||||
private static class MockIoSource extends AbstractTransactionalIoSource {
|
||||
|
||||
private boolean commitCalled = false;
|
||||
@@ -118,21 +72,4 @@ public class AbstractTransactionalIoSourceTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private void commit() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_COMMITTED);
|
||||
}
|
||||
|
||||
private void rollback() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
}
|
||||
|
||||
private void invokeUnknown() {
|
||||
TransactionSynchronizationUtils.invokeAfterCompletion(
|
||||
TransactionSynchronizationManager.getSynchronizations(),
|
||||
TransactionSynchronization.STATUS_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.springframework.core.io.AbstractResource;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
|
||||
/**
|
||||
* Tests for {@link StaxEventItemReader}.
|
||||
@@ -157,7 +156,7 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
source.skip();
|
||||
List second = (List) source.read();
|
||||
assertFalse(first.equals(second));
|
||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
source.reset(null);
|
||||
|
||||
assertEquals(second, source.read());
|
||||
}
|
||||
@@ -169,21 +168,21 @@ public class StaxEventItemReaderTests extends TestCase {
|
||||
|
||||
// rollback between deserializing records
|
||||
List first = (List) source.read();
|
||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
source.mark(null);
|
||||
List second = (List) source.read();
|
||||
assertFalse(first.equals(second));
|
||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
source.reset(null);
|
||||
|
||||
assertEquals(second, source.read());
|
||||
|
||||
// rollback while deserializing record
|
||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
source.reset(null);
|
||||
source.setFragmentDeserializer(new ExceptionFragmentDeserializer());
|
||||
try {
|
||||
source.read();
|
||||
}
|
||||
catch (Exception expected) {
|
||||
source.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
source.reset(null);
|
||||
}
|
||||
source.setFragmentDeserializer(deserializer);
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.oxm.Marshaller;
|
||||
import org.springframework.oxm.XmlMappingException;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.xml.transform.StaxResult;
|
||||
|
||||
@@ -67,9 +66,8 @@ public class StaxEventWriterItemWriterTests extends TestCase {
|
||||
*/
|
||||
public void testRollback() throws Exception {
|
||||
writer.write(record);
|
||||
|
||||
// rollback
|
||||
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_ROLLED_BACK);
|
||||
writer.reset(null);
|
||||
assertEquals("", outputFileContent());
|
||||
}
|
||||
|
||||
@@ -78,10 +76,9 @@ public class StaxEventWriterItemWriterTests extends TestCase {
|
||||
*/
|
||||
public void testCommit() throws Exception {
|
||||
writer.write(record);
|
||||
|
||||
// commit
|
||||
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
assertTrue(outputFileContent().indexOf(TEST_STRING) != NOT_FOUND);
|
||||
writer.mark(null);
|
||||
assertTrue(outputFileContent().contains(TEST_STRING));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +87,7 @@ public class StaxEventWriterItemWriterTests extends TestCase {
|
||||
public void testRestart() throws Exception {
|
||||
// write records
|
||||
writer.write(record);
|
||||
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
writer.mark(null);
|
||||
StreamContext streamContext = writer.getStreamContext();
|
||||
|
||||
// create new writer from saved restart data and continue writing
|
||||
@@ -134,7 +131,7 @@ public class StaxEventWriterItemWriterTests extends TestCase {
|
||||
put("attribute", "value");
|
||||
}});
|
||||
writer.open();
|
||||
writer.getSynchronization().afterCompletion(TransactionSynchronization.STATUS_COMMITTED);
|
||||
writer.mark(null);
|
||||
|
||||
assertTrue(outputFileContent().indexOf("<testroot attribute=\"value\"") != NOT_FOUND);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user