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");
}
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();
}
}
}
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");
}
Aggregations