BATCH-970: backported 2.0 fix - added call to DataSourceUtils to get connection for active transaction

This commit is contained in:
trisberg
2008-12-15 15:02:33 +00:00
parent 22fb6350e1
commit dabfda5cb3
2 changed files with 88 additions and 1 deletions

View File

@@ -33,6 +33,7 @@ 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;
@@ -170,7 +171,7 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i
Assert.state(dataSource != null, "DataSource must not be null.");
try {
this.con = dataSource.getConnection();
this.con = DataSourceUtils.getConnection(dataSource);
preparedStatement = this.con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT);
applyStatementSettings(preparedStatement);

View File

@@ -0,0 +1,86 @@
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 {
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);
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();
}
}