You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Dave <li...@a.leader-bg.com> on 2002/12/31 05:11:42 UTC

Infinite loop on invalid validation SQL query

If one is using DBCP package and enters an incorrect query (a query that would 
always fail) for the "validation query", then when a connection is being 
requested the code will enter an infinite loop in 
GenericObjectPool.borrowObject().

The problem would happen for any other object (not only Connection) if the 
validation always fails.

I suggest adding a counter to the validation loop, to be incremented every 
time the validation fails. If the specified count is reached, the loop should 
be terminated with exception, similar to the "Timeout".

Alternativelly, use the timeout for the validation loop as well, and append 
the number of times the validation failed during the wait period.


    public synchronized Object borrowObject() throws Exception {
	int validationCount = 0; // NEW <<<<
        long starttime = System.currentTimeMillis();
        for(;;) {

// MOVE HERE <<<<<
                            if(_maxWait > 0 && ((System.currentTimeMillis() - 
starttime) >= _maxWait)) {
                                throw new NoSuchElementException("Timeout 
waiting for idle object [Validation Failures = " + 
Integer.toString(validationCount) + "]");


            ObjectTimestampPair pair = null;
            // if there are any sleeping, just grab one of those
            try {
                pair = (ObjectTimestampPair)(_pool.removeFirst());
            } catch(NoSuchElementException e) { /* ignored */
            }
            // otherwise
            if(null == pair) {
                // check if we can create one
                // (note we know that the num sleeping is 0, else we wouldn't 
be here)
                if(_maxActive > 0 && _numActive < _maxActive) {
                    Object obj = _factory.makeObject();
                    pair = new ObjectTimestampPair(obj);
                } else {
                    // the pool is exhausted
                    switch(_whenExhaustedAction) {
                        case WHEN_EXHAUSTED_GROW:
                            Object obj = _factory.makeObject();
                            pair = new ObjectTimestampPair(obj);
                            break;
                        case WHEN_EXHAUSTED_FAIL:
                            throw new NoSuchElementException();
                        case WHEN_EXHAUSTED_BLOCK:
                            try {
                                if(_maxWait <= 0) {
                                    wait();
                                } else {
                                    wait(_maxWait);
                                }
                            } catch(InterruptedException e) {
                                // ignored
                            }
// MOVED ABOVE <<<<
//                            if(_maxWait > 0 && ((System.currentTimeMillis() 
- starttime) >= _maxWait)) {
//                                throw new NoSuchElementException("Timeout 
waiting for idle object");
                            } else {
                                continue; // keep looping
                            }
                        default:
                            throw new 
IllegalArgumentException("whenExhaustedAction " + _whenExhaustedAction + " 
not recognized.");
                    }
                }
            }
            _factory.activateObject(pair.value);
            if(_testOnBorrow && !_factory.validateObject(pair.value)) {
                try {
                    _factory.passivateObject(pair.value);
                } catch(Exception e) {
                    ; // ignored, we're throwing it out anyway
                }
                _factory.destroyObject(pair.value);
// NEW: sanity check <<<<<<
		if (validationCount++ > 1000000) {
                                throw new NoSuchElementException("Unable to 
aquire validated object. Is your validation condition correct?");
		}
            } else {
                _numActive++;
                return pair.value;
            }
        }
    }

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Infinite loop on invalid validation SQL query

Posted by Rodney Waldhoff <rw...@apache.org>.
Both these suggestions sound reasonable to me.

I'll try to get around to making these changes sometime this week.  A
patch, preferably one with unit tests, would expedite that process.

On Mon, 30 Dec 2002, Dave wrote:

> In addition to my previous email, I would suggest modifying
> BasicDataSource.createDataSource() to not validate on "" (empty string).
>
>         if (validationQuery != null && validationQuery.length != 0) {
>             connectionPool.setTestOnBorrow(true);
>         }
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>