JDBCTemplate setQueryTimeout特定于每个查询,即查询级别

时间:2014-01-02 18:11:14

标签: spring jdbc

我需要为各种查询范围设置查询超时,具体取决于它们提取的数据。即,每个查询都有自己的超时时间。

例如,查询A - > 10分钟
                  查询B - > 5分钟

现在如何使用getJDBCTemplate()设置这些不同的时序。当我尝试下面的代码片段时,超时被覆盖,并且无论设置如何,两个查询都会在同一时间超时!

Thread t1 = new Thread(new Runnable() {
public void run() {
       getJdbcTemplate().setQueryTimeout(5);
       List t = getJdbcTemplate()
                   .query("select top 10000 * from ABC",new RowMapper<T>(){
                   ..
       });

Thread t2 = new Thread(new Runnable() {
public void run() {
       getJdbcTemplate().setQueryTimeout(10);
       List t = getJdbcTemplate()
        .query("select top 30000 * from XYZ",new RowMapper<T>() {
                        ..
       });
t1.start();
t2.start();  

在上面的上下文中,两个查询都在第5分钟或第10分钟超时。有没有办法根据查询进行设置?请建议!

[UPDATE]

<bean id="dSource" class="com.xyz.DSource" >
    <property name="dataSource" ref="dataSource"/>
</bean>

public abstract class AbstractData  {
    private DSource dSource;
    public JdbcTemplate getJdbcTemplate(){

        ApplicationContext Ctx = ContextUtils.getApplicationContext(); 
        dSource = (DSource)Ctx.getBean("dSource");
        return dSource.getJDBCTemplate();
         }
}

public class DSource extends JdbcDaoSupport{
    public JdbcTemplate getJdbcTemplate(){
        return getJdbcTemplate();
    }
}

public Class Dao extends AbstractData{
     public void callQuery(){
        [AS already posted, t1 and t2 are 2 threads for 2 diff methods/queries using 
         getJDBCTemplate Of abstract classs]

       Thread 1 
       Thread 2
     }

}

2 个答案:

答案 0 :(得分:3)

超时被覆盖可能是因为你的JdbcTemplate是单例(请添加其配置)。要实现您的目标,您需要为每个类(或方法)提供专用的JdbcTemplate。

Thread t1 = new Thread(new Runnable() {
public void run() {
       JdbcTemplate template = new JdbcTemplate(dataSource);
       template.setQueryTimeout(5);
       List t = template
                   .query("select top 10000 * from ABC",new RowMapper<T>(){
                   ..
       });

我不认为这是理想的。可能更好的解决方案是使用纯jdbc并将超时直接设置为prpared语句

    Connection con = jdbcTemplate.getDataSource().getConnection()
    preparedstatement = con.prepareStatement(sql);
    preparedstatement.setQueryTimeout(theTimeout);

在这种情况下,您无需检查Spring是否会关闭声明和连接,或者您需要自己处理。

答案 1 :(得分:0)

Spring JdbcTemplate具有接受CallableStatementCreator / PreparedStatementCreator对象作为参数的方法变体。您可以使用这些对象来创建和配置语句。

例如,您可以编写CallableStatementCreator的实现来支持查询级超时,如下所示:

public class TimeoutCallableStatementCreator implements CallableStatementCreator {

    private final String callString;
    private final int timeout;

    public TimeoutCallableStatementCreator(String callString, int timeout) {
        Assert.notNull(callString, "Call string must not be null");
        this.callString = callString;
        this.timeout = timeout;
    }

    @Override
    public CallableStatement createCallableStatement(Connection con) throws SQLException {
        CallableStatement stmt = con.prepareCall(this.callString);
        stmt.setQueryTimeout(timeout);
        return stmt;
    }
}

注意:如果为JdbcTemplate设置超时,它将覆盖通过CallableStatementCreator / PreparedStatementCreator设置的超时。