diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java index 56916b12b..9d7aa0f79 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/JdbcCursorItemReader.java @@ -35,6 +35,7 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException; import org.springframework.jdbc.SQLWarningException; import org.springframework.jdbc.core.PreparedStatementSetter; import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.datasource.DataSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; import org.springframework.jdbc.support.SQLExceptionTranslator; @@ -144,7 +145,7 @@ public class JdbcCursorItemReader extends AbstractItemCountingItemStreamItemR * not set. */ public void afterPropertiesSet() throws Exception { - Assert.notNull(dataSource, "DataSOurce must be provided"); + Assert.notNull(dataSource, "DataSource must be provided"); Assert.notNull(sql, "The SQL query must be provided"); Assert.notNull(mapper, "RowMapper must be provided"); } @@ -170,7 +171,7 @@ public class JdbcCursorItemReader extends AbstractItemCountingItemStreamItemR 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); diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java new file mode 100644 index 000000000..e7b08b24f --- /dev/null +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java @@ -0,0 +1,57 @@ +package org.springframework.batch.item.database; + +import static org.easymock.EasyMock.*; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; + +import javax.sql.DataSource; + +import org.junit.Test; +import org.junit.internal.runners.JUnit4ClassRunner; +import org.junit.runner.RunWith; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallback; +import org.springframework.transaction.support.TransactionTemplate; + +@RunWith(JUnit4ClassRunner.class) +public class JdbcCursorItemReaderConfigTests { + + /* + * Should fail if trying to call getConnection() twice + */ + @Test + public void testUsesCurrentTransaction() throws Exception { + + DataSource ds = createMock(DataSource.class); + Connection con = createMock(Connection.class); + expect(con.getAutoCommit()).andReturn(false); + PreparedStatement ps = createMock(PreparedStatement.class); + expect(con.prepareStatement("select foo from bar", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, + ResultSet.HOLD_CURSORS_OVER_COMMIT)).andReturn(ps); + expect(ds.getConnection()).andReturn(con); + con.commit(); + replay(con); + replay(ds); + PlatformTransactionManager tm = new DataSourceTransactionManager(ds); + TransactionTemplate tt = new TransactionTemplate(tm); + final JdbcCursorItemReader reader = new JdbcCursorItemReader(); + reader.setDataSource(ds); + 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(); + return null; + } + }); + verify(ds); + } + +}