BATCH-970: leaving the 1.1 branch as it was - adding the optional transaction configuration to the new 2.0 version

This commit is contained in:
trisberg
2008-12-15 21:34:27 +00:00
parent 159ba9564e
commit da4cf938dd
2 changed files with 11 additions and 120 deletions

View File

@@ -33,7 +33,6 @@ import org.springframework.batch.item.support.AbstractBufferedItemReaderItemStre
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.jdbc.SQLWarningException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
@@ -80,7 +79,13 @@ import org.springframework.util.ClassUtils;
* transaction is rolled back, the current row can be moved back to the same row
* number as it was on when commit was called.
* </p>
*
*
* <p>
* NOTE that the cursor is opened using a separate connection from the rest of the
* processing in the step. This means that this reader also runs within its own
* JDBC transaction.
* </p>
*
* <p>
* Calling close on this {@link ItemStream} will cause all resources it is
* currently using to be freed. (Connection, ResultSet, etc). It is then illegal
@@ -134,9 +139,7 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i
private boolean driverSupportsAbsolute = false;
private boolean participateInExistingTransaction = false;
public JdbcCursorItemReader() {
public JdbcCursorItemReader() {
setName(ClassUtils.getShortName(JdbcCursorItemReader.class));
}
@@ -173,13 +176,9 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i
Assert.state(dataSource != null, "DataSource must not be null.");
try {
if (participateInExistingTransaction) {
this.con = DataSourceUtils.getConnection(dataSource);
}
else {
this.con = dataSource.getConnection();
}
preparedStatement = this.con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
// Note: this is a connection that is separate from the current transaction
this.con = dataSource.getConnection();
preparedStatement = this.con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
applyStatementSettings(preparedStatement);
if (this.preparedStatementSetter != null) {
@@ -387,19 +386,6 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i
this.driverSupportsAbsolute = driverSupportsAbsolute;
}
/**
* Indicate whether the cursor should be opened as part of an existing transaction or if it
* should be opened in its own transaction. The default is for the cursor to be opened in its
* own transaction. If you set this flag to true then you should wrap the DataSource in a
* {@link org.springframework.jdbc.datasource.SingleConnectionDataSource} to prevent the
* connection from being closed after each commit.
*
* @param participateInExistingTransaction <code>false</code> by default
*/
public void setParticipateInExistingTransaction(boolean participateInExistingTransaction) {
this.participateInExistingTransaction = participateInExistingTransaction;
}
/**
* Check the result set is in synch with the currentRow attribute. This is
* important to ensure that the user hasn't modified the current row.

View File

@@ -1,95 +0,0 @@
package org.springframework.batch.item.database;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.easymock.MockControl;
import junit.framework.TestCase;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JdbcCursorItemReaderConfigTests extends TestCase {
/*
* Should fail if trying to call getConnection() twice
*/
public void testUsesCurrentTransaction() throws Exception {
//TODO:
}
/*
* Should not fail if trying to call getConnection() twice
*/
public void testUsesItsOwnTransaction() throws Exception {
MockControl ctrlDataSource;
DataSource mockDataSource;
MockControl ctrlConnection;
Connection mockConnection;
MockControl ctrlPreparedStatement;
PreparedStatement mockPreparedStatement;
MockControl ctrlResultSet;
ResultSet mockResultSet;
ctrlResultSet = MockControl.createControl(ResultSet.class);
mockResultSet = (ResultSet) ctrlResultSet.getMock();
ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
mockPreparedStatement.executeQuery();
ctrlPreparedStatement.setReturnValue(mockResultSet);
mockPreparedStatement.getWarnings();
ctrlPreparedStatement.setDefaultReturnValue(null);
ctrlConnection = MockControl.createControl(Connection.class);
mockConnection = (Connection) ctrlConnection.getMock();
mockConnection.getMetaData();
ctrlConnection.setDefaultReturnValue(null);
mockConnection.getAutoCommit();
ctrlConnection.setDefaultReturnValue(false);
mockConnection.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
ctrlConnection.setReturnValue(mockPreparedStatement);
mockConnection.commit();
ctrlConnection.setDefaultVoidCallable();
mockConnection.close();
ctrlConnection.setDefaultVoidCallable();
ctrlDataSource = MockControl.createControl(DataSource.class);
mockDataSource = (DataSource) ctrlDataSource.getMock();
mockDataSource.getConnection();
ctrlDataSource.setReturnValue(mockConnection);
mockDataSource.getConnection();
ctrlDataSource.setReturnValue(mockConnection);
ctrlResultSet.replay();
ctrlDataSource.replay();
ctrlConnection.replay();
ctrlPreparedStatement.replay();
PlatformTransactionManager tm = new DataSourceTransactionManager(mockDataSource);
TransactionTemplate tt = new TransactionTemplate(tm);
final JdbcCursorItemReader reader = new JdbcCursorItemReader();
reader.setDataSource(mockDataSource);
reader.setSql("select foo from bar");
final ExecutionContext ec = new ExecutionContext();
tt.execute(
new TransactionCallback() {
public Object doInTransaction(TransactionStatus status) {
reader.open(ec);
reader.close(ec);
return null;
}
});
ctrlDataSource.verify();
}
}