Java 在执行CallableStatement之前,无法从该语句检索结果
我在应用程序中使用此方法来获取特定组织的子组织。它调用一个存储过程(创建一个临时表) StoredProcedureDAO.javaJava 在执行CallableStatement之前,无法从该语句检索结果,java,postgresql,stored-procedures,jdbc,callable-statement,Java,Postgresql,Stored Procedures,Jdbc,Callable Statement,我在应用程序中使用此方法来获取特定组织的子组织。它调用一个存储过程(创建一个临时表) StoredProcedureDAO.java private Connection dbConnection = null; private CallableStatement cstmt = null; private ResultSet results = null; 内部getChildrens(int siteId)方法 public ArrayList<String> getChild
private Connection dbConnection = null;
private CallableStatement cstmt = null;
private ResultSet results = null;
内部getChildrens(int siteId)方法
public ArrayList<String> getChildrens(int siteId)
{
ArrayList<String> childrenSites = new ArrayList<String>();
Connection pgConnection = getFreshDBConnection();
if (pgConnection == null) {
cat.error("getChildrens got a null connection");
return null;
}
try{
pgConnection.setAutoCommit(false);
cstmt = pgConnection.prepareCall("{ ? = call \"spGetChildSitesInfo\" ( ? ) }");
cstmt.registerOutParameter(1, Types.OTHER);
cstmt.setInt(2, siteId);
cstmt.execute();
results = (ResultSet) cstmt.getObject(1);
if(results != null){
while(results.next()){
childrenSites.add(results.getString(1));
}
}
cstmt.close();
pgConnection.commit();
pgConnection.close();
} catch (SQLException e){
try {
pgConnection.rollback();
cat.error("SQL Exception has occured while retriving the children", e);
} catch (Exception ex) {
cat.error("Error while connection rollback: ", e);
}
} finally {
try {
if(!pgConnection.isClosed()){
pgConnection.setAutoCommit(true);
pgConnection.close();
}
pgConnection = null;
} catch (Exception e) {
cat.error("Error while closing the connection: "+e);
}
}
return childrenSites;
}
在实验后添加更多信息
这是我的构造函数(私有)
下面是getInstance()
我使用以下命令调用getChildrens()
StoredProcedureDAO dao = StoredProcedureDAO.getInstance();
children = dao.getChildrens(site_id);
现在,如果我删除if语句
//if (myself == null)
在这种情况下,我没有得到例外。
我正在使用postgresql-9.0-801.jdbc4.jar驱动程序。谁能解释一下原因吗?您遇到了多线程问题。看起来您正在不同线程之间共享ResultSet成员变量(servlet(或JSP)可以由多个线程共享),因此出现了错误。您确定要创建多个
StoredProcedureDAO
实例吗?您有多线程问题。看起来您正在不同线程之间共享ResultSet成员变量(servlet(或JSP)可以由多个线程共享),因此出现了错误。确实要创建多个实例吗?您应该在finally中关闭结果。您可以尝试。您应该在finally中关闭结果。您可以尝试。问题是跨线程共享非线程安全资源。停止尝试手动管理所有数据库资源,让Spring为您处理所有这些资源。这将使您免于陷入困境。问题在于跨线程共享非线程安全的资源。停止尝试手动管理所有数据库资源,让Spring为您处理所有这些资源。这将使您免于陷入困境。pgConnection在哪里打开?示例代码中它正在关闭,这可能是第二次单击出现问题的原因。@g051051我已经编辑了我的问题,以显示连接打开的位置。pgConnection在哪里打开?示例代码中正在关闭该问题,这可能是第二次单击出现问题的原因。@g051051我已编辑了我的问题,以显示连接在何处打开Hanks ivy。很明显,问题出在线程上。有时我会变得如此愚蠢。我用一些附加信息编辑了这个问题。你能编辑你的答案解释我的原因吗;使用Spring这样的框架在web上下文中处理DAO的线程安全注入是明智的。您的单例getInstance()
应该同步以确保安全,但真正的问题在于ResultSet results
是DAO的成员。您仍然在跨线程共享这个DAO实例(与resultSet成员),并且每个实例都在覆盖resultSet。resultSet应该是线程的局部变量!谢谢艾薇。很明显,问题出在线程上。有时我会变得如此愚蠢。我用一些附加信息编辑了这个问题。你能编辑你的答案解释我的原因吗;使用Spring这样的框架在web上下文中处理DAO的线程安全注入是明智的。您的单例getInstance()
应该同步以确保安全,但真正的问题在于ResultSet results
是DAO的成员。您仍然在跨线程共享这个DAO实例(与resultSet成员),并且每个实例都在覆盖resultSet。resultSet应该是线程的局部变量!事实上,这是一个旧的应用程序,我正在尝试修复当前的错误,所以我不能改变整个设计。关于使用更好的框架,您是对的。我正在使用spring开发另一个应用程序,它非常好technology@anu:我不是说完全改变应用程序的基础结构。只需创建一个JdbcTemplate并使用它的方法。这是一个旧的应用程序,我正在尝试修复当前的bug,所以我不能改变整个设计。关于使用更好的框架,您是对的。我正在使用spring开发另一个应用程序,它非常好technology@anu:我不是说完全改变应用程序的基础结构。只需创建一个JdbcTemplate并使用它的方法。它将为您管理所有的资源。它一开始就不起作用。你可以阅读我编辑的问题。无论如何,它一开始就不起作用。你可以阅读我编辑的问题。反正是tnx
public static StoredProcedureDAO getInstance()
{
if (myself == null)
myself = new StoredProcedureDAO();
return myself;
}
StoredProcedureDAO dao = StoredProcedureDAO.getInstance();
children = dao.getChildrens(site_id);
//if (myself == null)