在H2数据库上调用过程时,我遇到了一个奇怪的行为:前几次调用(到目前为止为1到3)将成功返回,然后下一次调用将始终抛出org.h2.jdbc.JdbcSQLException: Parameter "#1" is not set;
,其中第一个参数应该是OUT参数。
我还注意到这个失败模式与DataSource
相关:多个DataSource
连接相同的H2数据库,每个都能够在持续抛出错误之前调用该过程几次
看起来等待足够长时间会使Datasource
再次调用该过程。虽然我不确定等待需要多长时间,但至少需要10分钟。
使用以下查询创建过程:
CREATE OR REPLACE ALIAS ps_sleep as$$
String ps_sleep(int seconds) throws InterruptedException {
Thread.sleep(seconds * 1000);
return "DB Procedure : " + seconds + " seconds waited" ;
}
$$;
由以下Java代码执行:
((DataSource)getJNDIResource(datasourceJndiUri)).getConnection().prepareStatement(PS_SLEEP_QUERY).execute();
然后通过以下Java代码调用该过程:
InitialContext context = new InitialContext();
DataSource ds = (DataSource) context.lookup(datasourceJndiUri);
Connection con = ds.getConnection();
CallableStatement cs = con.prepareCall("{?=call PS_SLEEP(?)}");
cs.registerOutParameter(1, java.sql.Types.VARCHAR);
cs.setInt(2, input_proc_timer);
cs.execute();
我确保input_proc_timer
的值始终为int
。
stacktrace如下:
org.h2.jdbc.JdbcSQLException: Parameter "#1" is not set; SQL statement:
?=call PS_SLEEP(?) [90012-173]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:331)
at org.h2.message.DbException.get(DbException.java:171)
at org.h2.message.DbException.get(DbException.java:148)
at org.h2.expression.Parameter.checkSet(Parameter.java:80)
at org.h2.command.Prepared.checkParameters(Prepared.java:163)
at org.h2.command.CommandContainer.query(CommandContainer.java:90)
at org.h2.command.Command.executeQuery(Command.java:195)
at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:189)
at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.execute(WrappedPreparedStatement.java:404)
at my.application.SomeServlet.doGet(SomeServlet.java:49)
[...]
我在wildfly 8.1.0及其打包的H2数据库下运行它,我相信它是1.3版本(h2模块包含一个h2-1.3.173.jar)。我正在使用standalone-full.xml
配置文件,我没有特别修改过。
我欢迎任何解决这个问题的方法,如果有人能解释这种行为是如何发生的,我会特别高兴。
答案 0 :(得分:0)
看起来这是h2
版本的错误。
This github issue让我走上了这条轨道,尽管我仍在使用1.3.170版本重现错误,但升级到1.4.193解决了我的问题。