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>