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. connectionLock.writeLock().lock(); 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. connectionLock.writeLock().unlock(); } }
protected void executeInternal( UpdateExpr updateExpr, Dataset dataset, BindingSet bindings, boolean includeInferred) throws SailException { /* * TODO this method should really be defined abstract, but for * backward-compatibility purposes with third-party SAIL implementations * we provide a default implementation for now. */ ValueFactory vf = sailBase.getValueFactory(); SailUpdateExecutor executor = new SailUpdateExecutor(this, vf, false); executor.executeUpdate(updateExpr, dataset, bindings, includeInferred); }