我正在使用连接池连接到AS / 400。我试图用准备好的语句获取动态数量的订单。当我使用statement参数来定义要获取的最大订单数时,似乎发生了某种类型的缓存。在第一次通话时,我得到正确的订单数量,但在接下来的通话中,即使我更改了要获取的最大订单数量,我也会获得与第一次通话相同的计数。如果我在每次通话时打开一个新连接,一切正常。如果我在数据源上调用setReuseConnections(false),一切正常。如果我删除“FETCH FIRST [x] ROWS ONLY”语句的参数并在SQL文本中使用占位符替换为每次调用时要获取的最大订单数,那么一切正常。
正在进行什么样的缓存?我可以用另一种方式绕过它吗?这是一个错误吗?
这是一个示例应用程序,您只需要连接的AS / 400数据库!
package com.richelieu.web.test.as400;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.ibm.as400.access.AS400JDBCManagedConnectionPoolDataSource;
public class CachingPreparedStatement {
// Database connection info
private static final String SERVER_NAME = "<server ip address>";
private static final String LIBRAIRIES = "<library name>";
private static final String USER = "<user name>";
private static final String PASSWORD = "<password>";
// Query parameters
private static final BigDecimal DATE_FROM = new BigDecimal("20170701000000"); //(format: YYYMMDDHHMMSS)
private static final int MAX_ORDER_COUNT_1 = 1;
private static final int MAX_ORDER_COUNT_2 = 2;
private static final int MAX_ORDER_COUNT_3 = 3;
private static final String SELECT_WITH_ORDER_COUNT_PARAM =
"SELECT <column> FROM <table> WHERE <tsinsert> >= ? ORDER BY SCCONO FETCH FIRST ? ROWS ONLY";
public static void main(String[] args) {
DataSource ds = initDataSource();
System.out.println("Test with param:");
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_1);
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_2);
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_3);
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_1);
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_2);
testFetchOrdersWithMaxOrderCountParam(ds, MAX_ORDER_COUNT_3);
}
private static void testFetchOrdersWithMaxOrderCountParam(DataSource ds, int maxOrderCount) {
try (Connection connection = ds.getConnection()) {
int actualOrderCount = fetchOrdersWithMaxOrderCountParam(connection, DATE_FROM, maxOrderCount);
System.out.println(String.format("Order count: %d", actualOrderCount));
} catch (SQLException pEx) {
throw new RuntimeException(pEx.getMessage(), pEx);
}
}
public static int fetchOrdersWithMaxOrderCountParam(Connection pConnection, BigDecimal dateFrom, int maxOrderCount) {
try (PreparedStatement statement = pConnection.prepareStatement(SELECT_WITH_ORDER_COUNT_PARAM)) {
statement.setBigDecimal(1, dateFrom);
statement.setInt(2, maxOrderCount);
int orderCount = 0;
try (ResultSet rs = statement.executeQuery()) {
while(rs.next()) {
orderCount++;
}
}
return orderCount;
} catch (SQLException pEx) {
throw new RuntimeException(pEx.getMessage(), pEx);
}
}
private static AS400JDBCManagedConnectionPoolDataSource initDataSource() {
AS400JDBCManagedConnectionPoolDataSource ds = new AS400JDBCManagedConnectionPoolDataSource(SERVER_NAME, USER, PASSWORD);
ds.setLibraries(LIBRAIRIES);
ds.setMinPoolSize(1);
ds.setMaxPoolSize(2);
//ds.setBlockCriteria(0);
//ds.setBlockSize(0);
//ds.setBlockCriteria(0);
//ds.setExtendedDynamic(false);
//ds.setReuseConnections(false); // only setting I found to resolve my "caching" problem
return ds;
}
}
提前致谢。