我在我的一个项目中使用Spring JdbcTemplate,现在,当它有非常多的请求时 - 我开始面对这个例外:
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback;
uncategorized SQLException for SQL [{? = call API.get_data_for_nb(?, ?)}];
SQL state [99999]; error code [17009]; Closed Statement;
nested exception is java.sql.SQLException: Closed Statement
因此,当您尝试执行已关闭的语句时会收到Closed Statement异常,但在我的情况下,我不会自己关闭它 - 我完全使用JdbcTemplate。那么,首先,可能是什么原因呢?
JdbcTemplate对象本身以这种方式包含在@Stateless
EJB中:
@Stateless(name = "NbEdwServiceEJB")
public class NbEdwServiceBean implements NbEdwServiceLocal, NbEdwServiceRemote {
@Resource(mappedName = JNDI)
private DataSource dataSource;
private static volatile JdbcTemplate jdbcTemplate;
@PostConstruct
protected void construct() {
synchronized (NbEdwServiceBean.class) {
if (jdbcTemplate == null) {
jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
}
}
}
private String getDataFromDB(final String request, final int isDigitalSignVerified) {
String response = null;
try {
response = jdbcTemplate.execute(SQL_GET_DATA, new CallableStatementCallback<String>() {
public String doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
cs.registerOutParameter(1, Types.VARCHAR);
cs.setInt(2, isDigitalSignVerified);
cs.setString(3, request);
cs.executeUpdate();
return cs.getString(1);
}
});
} catch (DataAccessException ex) {
LOGGER.error("getDataFromDB()", ex);
}
return response;
}
}
我知道这可能不是完全正确的方法,我可以为每个无状态bean创建JdbcTemplate实例 - 所以我可能会这样做。那么,其次,为什么会发生这种情况呢?我的假设是JdbcTemplate的执行方法不是线程安全的,但有人可以给出正在发生的事情的完整解释吗?
如果有问题,我在WebLogic 10.3.5上运行JEE版本5。
答案 0 :(得分:0)
关于Singleton和EE5,有一些替代方案。一个是供应商特定的扩展,例如JBoss 5.x有服务bean提供Singleton + JMX。第二种解决方案是使用与EE5兼容的早期版本的Jboss Seam。第三种方法是使用Servlet API中的ServerContext。
你在@PostConstuct尝试做的事情肯定不好。 SLSB中的非最终静态是不行的。
我建议看看Spring框架参考中的第29.3节,它描述了EJB - Spring集成,该部分的一个例子:
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class MyFacadeEJB implements MyFacadeLocal {
// automatically injected with a matching Spring bean
@Autowired
private MyComponent myComp;
// for business method, delegate to POJO service impl.
public String myFacadeMethod(...) {
return myComp.myMethod(...);
}