From da4cf938dd199a677b25832a8f8af458c296165c Mon Sep 17 00:00:00 2001 From: trisberg Date: Mon, 15 Dec 2008 21:34:27 +0000 Subject: [PATCH] BATCH-970: leaving the 1.1 branch as it was - adding the optional transaction configuration to the new 2.0 version --- .../item/database/JdbcCursorItemReader.java | 36 +++---- .../JdbcCursorItemReaderConfigTests.java | 95 ------------------- 2 files changed, 11 insertions(+), 120 deletions(-) delete mode 100644 spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java 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 72628a203..718163ff4 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 @@ -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. *

- * + * + *

+ * 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. + *

+ * *

* 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 false 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. 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 deleted file mode 100644 index 1eee14635..000000000 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/JdbcCursorItemReaderConfigTests.java +++ /dev/null @@ -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(); - } - -}