public final void close()
throws SailException
{
// obtain an exclusive lock so that any further operations on this
// connection (including those from any concurrent threads) are blocked.
Lock conLock = getExclusiveConnectionLock();
try {
if (isOpen) {
try {
while (true) {
SailBaseIteration ci = null;
synchronized (activeIterations) {
if (activeIterations.isEmpty()) {
break;
}
else {
ci = activeIterations.remove(0);
}
}
try {
ci.forceClose();
}
catch (SailException e) {
throw e;
}
catch (Exception e) {
throw new SailException(e);
}
}
assert activeIterations.isEmpty();
if (txnActive) {
logger.warn("Rolling back transaction due to connection close", new Throwable());
try {
// Use internal method to avoid deadlock: the public
// rollback method will try to obtain a connection lock
rollbackInternal();
}
finally {
txnActive = false;
}
}
closeInternal();
}
finally {
isOpen = false;
sailBase.connectionClosed(this);
}
}
}
finally {
// Release the exclusive lock. Any threads waiting to obtain a
// non-exclusive read lock will get one and then fail with an
// IllegalStateException, because the connection is no longer open.
conLock.release();
}
}