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:
dsyer
2008-01-31 22:36:26 +00:00
parent f5d8a32cdb
commit 2c3d43d7bd
27 changed files with 194 additions and 631 deletions

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);