Spring JdbcTemplate线程安全吗?

时间:2016-11-18 10:01:27

标签: java spring multithreading ejb

我在我的一个项目中使用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。

1 个答案:

答案 0 :(得分:0)

@Tolegen Izbassar我很遗憾你被EE5困住了。

关于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(...);
}