From 159ba9564efe5690148538e88980f76f8a2d20cb Mon Sep 17 00:00:00 2001 From: trisberg Date: Mon, 15 Dec 2008 17:20:17 +0000 Subject: [PATCH] BATCH-970: made the transaction participation configurable --- .../item/database/JdbcCursorItemReader.java | 26 ++++++++++++++++--- .../JdbcCursorItemReaderConfigTests.java | 13 ++++++++-- 2 files changed, 34 insertions(+), 5 deletions(-) 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 ea53d9556..72628a203 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 @@ -134,7 +134,9 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i private boolean driverSupportsAbsolute = false; - public JdbcCursorItemReader() { + private boolean participateInExistingTransaction = false; + + public JdbcCursorItemReader() { setName(ClassUtils.getShortName(JdbcCursorItemReader.class)); } @@ -171,8 +173,13 @@ public class JdbcCursorItemReader extends AbstractBufferedItemReaderItemStream i Assert.state(dataSource != null, "DataSource must not be null."); try { - this.con = DataSourceUtils.getConnection(dataSource); - preparedStatement = this.con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, + 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, ResultSet.HOLD_CURSORS_OVER_COMMIT); applyStatementSettings(preparedStatement); if (this.preparedStatementSetter != null) { @@ -380,6 +387,19 @@ 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 index eadec699b..1eee14635 100644 --- 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 @@ -18,10 +18,17 @@ import java.sql.ResultSet; public class JdbcCursorItemReaderConfigTests extends TestCase { + /* + * Should fail if trying to call getConnection() twice + */ + public void testUsesCurrentTransaction() throws Exception { + //TODO: + } + /* - * Should fail if trying to call getConnection() twice + * Should not fail if trying to call getConnection() twice */ - public void testUsesCurrentTransaction() throws Exception { + public void testUsesItsOwnTransaction() throws Exception { MockControl ctrlDataSource; DataSource mockDataSource; MockControl ctrlConnection; @@ -59,6 +66,8 @@ public class JdbcCursorItemReaderConfigTests extends TestCase { mockDataSource = (DataSource) ctrlDataSource.getMock(); mockDataSource.getConnection(); ctrlDataSource.setReturnValue(mockConnection); + mockDataSource.getConnection(); + ctrlDataSource.setReturnValue(mockConnection); ctrlResultSet.replay(); ctrlDataSource.replay();