Search in sources :

Example 1 with LockedDocumentMap

use of org.exist.storage.lock.LockedDocumentMap in project exist by eXist-db.

the class RpcConnection method beginProtected.

protected LockedDocumentMap beginProtected(final DBBroker broker, final Map<String, Object> parameters) throws EXistException, PermissionDeniedException {
    final String protectColl = (String) parameters.get(RpcAPI.PROTECTED_MODE);
    if (protectColl == null) {
        return null;
    }
    int retries = BEGIN_PROTECTED_MAX_LOCKING_RETRIES == -1 ? -1 : BEGIN_PROTECTED_MAX_LOCKING_RETRIES - 2;
    do {
        MutableDocumentSet docs = null;
        final LockedDocumentMap lockedDocuments = new LockedDocumentMap();
        final LockMode documentLockMode = LockMode.WRITE_LOCK;
        final LockMode collectionLockMode = broker.getBrokerPool().getLockManager().relativeCollectionLockMode(LockMode.READ_LOCK, documentLockMode);
        try (final Collection coll = broker.openCollection(XmldbURI.createInternal(protectColl), collectionLockMode)) {
            docs = new DefaultDocumentSet();
            coll.allDocs(broker, docs, true, lockedDocuments, documentLockMode);
            return lockedDocuments;
        } catch (final LockException e) {
            LOG.warn("Deadlock detected. Starting over again. Docs: {}; locked: {}. Cause: {}", docs.getDocumentCount(), lockedDocuments.size(), e.getMessage());
            lockedDocuments.unlock();
        }
        retries--;
    } while (retries >= -1);
    throw new EXistException("Unable to beginProtected after " + BEGIN_PROTECTED_MAX_LOCKING_RETRIES + " retries");
}
Also used : Collection(org.exist.collections.Collection) LockedDocumentMap(org.exist.storage.lock.LockedDocumentMap) LockMode(org.exist.storage.lock.Lock.LockMode) EXistException(org.exist.EXistException)

Example 2 with LockedDocumentMap

use of org.exist.storage.lock.LockedDocumentMap in project exist by eXist-db.

the class RpcConnection method doQuery.

protected QueryResult doQuery(final DBBroker broker, final CompiledXQuery compiled, final NodeSet contextSet, final Map<String, Object> parameters) throws XPathException, EXistException, PermissionDeniedException {
    final XQuery xquery = broker.getBrokerPool().getXQueryService();
    checkPragmas(compiled.getContext(), parameters);
    LockedDocumentMap lockedDocuments = null;
    try {
        final long start = System.currentTimeMillis();
        lockedDocuments = beginProtected(broker, parameters);
        if (lockedDocuments != null) {
            compiled.getContext().setProtectedDocs(lockedDocuments);
        }
        final Properties outputProperties = new Properties();
        final Sequence result = xquery.execute(broker, compiled, contextSet, outputProperties);
        // pass last modified date to the HTTP response
        HTTPUtils.addLastModifiedHeader(result, compiled.getContext());
        LOG.info("query took {}ms.", System.currentTimeMillis() - start);
        return new QueryResult(result, outputProperties);
    } catch (final XPathException e) {
        return new QueryResult(e);
    } finally {
        if (lockedDocuments != null) {
            lockedDocuments.unlock();
        }
    }
}
Also used : LockedDocumentMap(org.exist.storage.lock.LockedDocumentMap)

Example 3 with LockedDocumentMap

use of org.exist.storage.lock.LockedDocumentMap in project exist by eXist-db.

the class LocalXPathQueryService method beginProtected.

/**
 * Execute all following queries in a protected environment.
 * Protected means: it is guaranteed that documents referenced by the
 * query or the result set are not modified by other threads
 * until {@link #endProtected} is called.
 */
@Override
public void beginProtected() throws XMLDBException {
    try {
        int retries = BEGIN_PROTECTED_MAX_LOCKING_RETRIES == -1 ? -1 : BEGIN_PROTECTED_MAX_LOCKING_RETRIES - 2;
        boolean deadlockCaught;
        do {
            reservedBroker = brokerPool.get(Optional.of(user));
            deadlockCaught = false;
            MutableDocumentSet docs = null;
            try {
                final org.exist.collections.Collection coll = reservedBroker.getCollection(collection.getPathURI());
                lockedDocuments = new LockedDocumentMap();
                docs = new DefaultDocumentSet();
                coll.allDocs(reservedBroker, docs, true, lockedDocuments, LockMode.WRITE_LOCK);
                return;
            } catch (final LockException e) {
                LOG.warn("Deadlock detected. Starting over again. Docs: {}; locked: {}. Cause: {}", docs.getDocumentCount(), lockedDocuments.size(), e.getMessage());
                lockedDocuments.unlock();
                reservedBroker.close();
                deadlockCaught = true;
            } catch (final PermissionDeniedException e) {
                throw new XMLDBException(ErrorCodes.PERMISSION_DENIED, "Permission denied on document");
            }
            retries--;
        } while (deadlockCaught && retries >= -1);
    } catch (final EXistException e) {
        if (reservedBroker != null) {
            reservedBroker.close();
        }
        throw new XMLDBException(ErrorCodes.VENDOR_ERROR, e.getMessage());
    }
    throw new XMLDBException(ErrorCodes.VENDOR_ERROR, "Unable to beginProtected after " + BEGIN_PROTECTED_MAX_LOCKING_RETRIES + " retries");
}
Also used : MutableDocumentSet(org.exist.dom.persistent.MutableDocumentSet) DefaultDocumentSet(org.exist.dom.persistent.DefaultDocumentSet) LockException(org.exist.util.LockException) LockedDocumentMap(org.exist.storage.lock.LockedDocumentMap) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException)

Aggregations

LockedDocumentMap (org.exist.storage.lock.LockedDocumentMap)3 EXistException (org.exist.EXistException)2 Collection (org.exist.collections.Collection)1 DefaultDocumentSet (org.exist.dom.persistent.DefaultDocumentSet)1 MutableDocumentSet (org.exist.dom.persistent.MutableDocumentSet)1 PermissionDeniedException (org.exist.security.PermissionDeniedException)1 LockMode (org.exist.storage.lock.Lock.LockMode)1 LockException (org.exist.util.LockException)1