Search in sources :

Example 1 with ODistributedRecordLockedException

use of com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException in project orientdb by orientechnologies.

the class ODistributedResponseManager method manageConflicts.

protected RuntimeException manageConflicts() {
    if (!groupResponsesByResult || request.getTask().getQuorumType() == OCommandDistributedReplicateRequest.QUORUM_TYPE.NONE)
        // NO QUORUM
        return null;
    if (dManager.getNodeStatus() != ODistributedServerManager.NODE_STATUS.ONLINE)
        // CURRENT NODE OFFLINE: JUST RETURN
        return null;
    final int bestResponsesGroupIndex = getBestResponsesGroup();
    final List<ODistributedResponse> bestResponsesGroup = responseGroups.get(bestResponsesGroupIndex);
    final int maxCoherentResponses = bestResponsesGroup.size();
    final int conflicts = getExpectedResponses() - (maxCoherentResponses);
    if (isMinimumQuorumReached(true)) {
        // QUORUM SATISFIED
        if (responseGroups.size() == 1)
            // NO CONFLICT
            return null;
        if (checkNoWinnerCase(bestResponsesGroup))
            // TODO: CALL THE RECORD CONFLICT PIPELINE
            return null;
        if (fixNodesInConflict(bestResponsesGroup, conflicts))
            // FIX SUCCEED
            return null;
    }
    // QUORUM HASN'T BEEN REACHED
    if (ODistributedServerLog.isDebugEnabled()) {
        ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Detected %d node(s) in timeout or in conflict and quorum (%d) has not been reached, rolling back changes for request (%s)", conflicts, quorum, request);
        ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, composeConflictMessage());
    }
    if (!undoRequest()) {
        // SKIP UNDO
        return null;
    }
    // CHECK IF THERE IS AT LEAST ONE ODistributedRecordLockedException or OConcurrentCreateException
    for (Object r : responses.values()) {
        if (r instanceof ODistributedRecordLockedException)
            throw (ODistributedRecordLockedException) r;
        else if (r instanceof OConcurrentCreateException)
            throw (OConcurrentCreateException) r;
    }
    final Object goodResponsePayload = bestResponsesGroup.isEmpty() ? null : bestResponsesGroup.get(0).getPayload();
    if (goodResponsePayload instanceof RuntimeException)
        // RESPONSE IS ALREADY AN EXCEPTION: THROW THIS
        return (RuntimeException) goodResponsePayload;
    else if (goodResponsePayload instanceof Throwable)
        return OException.wrapException(new ODistributedException(composeConflictMessage()), (Throwable) goodResponsePayload);
    else {
        if (responseGroups.size() <= 2) {
            // CHECK IF THE BAD RESPONSE IS AN EXCEPTION, THEN PROPAGATE IT
            for (int i = 0; i < responseGroups.size(); ++i) {
                if (i == bestResponsesGroupIndex)
                    continue;
                final List<ODistributedResponse> badResponses = responseGroups.get(i);
                if (badResponses.get(0).getPayload() instanceof RuntimeException)
                    return (RuntimeException) badResponses.get(0).getPayload();
            }
        }
        return new ODistributedOperationException(composeConflictMessage());
    }
}
Also used : ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) OConcurrentCreateException(com.orientechnologies.orient.core.exception.OConcurrentCreateException) ODistributedOperationException(com.orientechnologies.orient.server.distributed.task.ODistributedOperationException)

Example 2 with ODistributedRecordLockedException

use of com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException in project orientdb by orientechnologies.

the class ODistributedResponseManager method fixNodesInConflict.

protected boolean fixNodesInConflict(final List<ODistributedResponse> bestResponsesGroup, final int conflicts) {
    // NO FIFTY/FIFTY CASE: FIX THE CONFLICTED NODES BY OVERWRITING THE RECORD WITH THE WINNER'S RESULT
    final ODistributedResponse goodResponse = bestResponsesGroup.get(0);
    if (goodResponse.getPayload() instanceof Throwable)
        return false;
    ODistributedServerLog.debug(this, dManager.getLocalNodeName(), null, DIRECTION.NONE, "Detected %d conflicts, but the quorum (%d) has been reached. Fixing remote records. Request (%s)", conflicts, quorum, request);
    for (List<ODistributedResponse> responseGroup : responseGroups) {
        if (responseGroup != bestResponsesGroup) {
            // CONFLICT GROUP: FIX THEM ONE BY ONE
            for (ODistributedResponse r : responseGroup) {
                if (r.getPayload() instanceof ODistributedRecordLockedException)
                    // NO FIX, THE RECORD WAS LOCKED
                    return false;
                final ORemoteTask fixTask = ((OAbstractReplicatedTask) request.getTask()).getFixTask(request, request.getTask(), r.getPayload(), goodResponse.getPayload(), r.getExecutorNodeName(), dManager);
                if (fixTask == null)
                    // FIX NOT AVAILABLE: UNDO THE ENTIRE OPERATION
                    return false;
                ODistributedServerLog.debug(this, dManager.getLocalNodeName(), r.getExecutorNodeName(), DIRECTION.OUT, "Sending fix message (%s) for response (%s) on request (%s) to be: %s", fixTask, r, request, goodResponse);
                dManager.sendRequest(request.getDatabaseName(), null, OMultiValue.getSingletonList(r.getExecutorNodeName()), fixTask, dManager.getNextMessageIdCounter(), ODistributedRequest.EXECUTION_MODE.NO_RESPONSE, null, null);
            }
        }
    }
    return true;
}
Also used : ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) ORemoteTask(com.orientechnologies.orient.server.distributed.task.ORemoteTask) OAbstractReplicatedTask(com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)

Example 3 with ODistributedRecordLockedException

use of com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException in project orientdb by orientechnologies.

the class ODistributedDatabaseImpl method lockRecord.

@Override
public boolean lockRecord(final ORID rid, final ODistributedRequestId iRequestId, final long timeout) {
    // TODO: IMPROVE THIS BY RECEIVING THE RECORD AS PARAMETER INSTEAD OF RELOADING IT
    ORawBuffer originalRecord = null;
    if (rid.isPersistent()) {
        final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.INSTANCE.getIfDefined();
        if (db != null)
            originalRecord = db.getStorage().getUnderlying().readRecord((ORecordId) rid, null, false, true, null).getResult();
    }
    final ODistributedLock lock = new ODistributedLock(iRequestId, originalRecord);
    boolean newLock = true;
    ODistributedLock currentLock = lockManager.putIfAbsent(rid, lock);
    if (currentLock != null) {
        if (iRequestId.equals(currentLock.reqId)) {
            // SAME ID, ALREADY LOCKED
            ODistributedServerLog.debug(this, localNodeName, null, DIRECTION.NONE, "Distributed transaction: %s locked record %s in database '%s' owned by %s (thread=%d)", iRequestId, rid, databaseName, currentLock.reqId, Thread.currentThread().getId());
            currentLock = null;
            newLock = false;
        } else {
            // TRY TO RE-LOCK IT UNTIL TIMEOUT IS EXPIRED
            final long startTime = System.currentTimeMillis();
            do {
                try {
                    if (timeout > 0) {
                        if (!currentLock.lock.await(timeout, TimeUnit.MILLISECONDS))
                            continue;
                    } else
                        currentLock.lock.await();
                    currentLock = lockManager.putIfAbsent(rid, lock);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            } while (currentLock != null && (timeout == 0 || System.currentTimeMillis() - startTime < timeout));
        }
    }
    //
    if (ODistributedServerLog.isDebugEnabled())
        if (currentLock == null) {
            ODistributedServerLog.debug(this, localNodeName, null, DIRECTION.NONE, "Distributed transaction: %s locked record %s in database '%s' (thread=%d)", iRequestId, rid, databaseName, Thread.currentThread().getId());
        } else {
            ODistributedServerLog.debug(this, localNodeName, null, DIRECTION.NONE, "Distributed transaction: %s cannot lock record %s in database '%s' owned by %s (thread=%d)", iRequestId, rid, databaseName, currentLock.reqId, Thread.currentThread().getId());
        }
    if (currentLock != null)
        throw new ODistributedRecordLockedException(manager.getLocalNodeName(), rid, currentLock.reqId, timeout);
    return newLock;
}
Also used : ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) ORawBuffer(com.orientechnologies.orient.core.storage.ORawBuffer) ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal) ORecordId(com.orientechnologies.orient.core.id.ORecordId)

Example 4 with ODistributedRecordLockedException

use of com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException in project orientdb by orientechnologies.

the class HALocalGraphTest method startThread.

private Runnable startThread(final int id, final OrientGraphFactory graphFactory) {
    Runnable th = new Runnable() {

        @Override
        public void run() {
            // OrientBaseGraph graph = new OrientGraph(getDBURL());
            // OrientGraph graph = graphFactory.getTx();
            boolean useSQL = false;
            StringBuilder sb = new StringBuilder(".");
            for (int m = 0; m < id; m++) {
                sb.append(".");
            }
            long st = System.currentTimeMillis();
            try {
                String query = "select from Test where prop2='v2-1'";
                boolean isRunning = true;
                for (int i = 1; i < TOTAL_CYCLES_PER_THREAD && isRunning; i++) {
                    if ((i % 2500) == 0) {
                        long et = System.currentTimeMillis();
                        log(sb.toString() + " [" + id + "] Total Records Processed: [" + i + "] Current: [2500] Time taken: [" + (et - st) / 1000 + "] seconds");
                        st = System.currentTimeMillis();
                    }
                    if (sleep > 0)
                        Thread.sleep(sleep);
                    OrientGraph graph = graphFactory.getTx();
                    if (!graph.getRawGraph().getURL().startsWith("remote:"))
                        Assert.assertTrue(graph.getVertexType("Test").getClusterSelection() instanceof OLocalClusterWrapperStrategy);
                    try {
                        if (useSQL) {
                            boolean update = true;
                            boolean isException = false;
                            String sql = "Update Test set prop5='" + String.valueOf(System.currentTimeMillis()) + "', updateTime='" + new Date().toString() + "' where prop2='v2-1'";
                            for (int k = 0; k < 10 && update; k++) {
                                try {
                                    graph.command(new OCommandSQL(sql)).execute();
                                    if (isException) {
                                        log("********** [" + id + "][" + k + "] Update success after distributed lock Exception");
                                    }
                                    update = false;
                                    break;
                                } catch (ONeedRetryException ex) {
                                    if (ex instanceof OConcurrentModificationException || ex.getCause() instanceof OConcurrentModificationException) {
                                    } else {
                                        isException = true;
                                        log("*$$$$$$$$$$$$$$ [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ? ex.getCause() : "--") + "] ");
                                    }
                                } catch (ODistributedException ex) {
                                    if (ex.getCause() instanceof OConcurrentModificationException) {
                                    } else {
                                        isException = true;
                                        log("*$$$$$$$$$$$$$$ [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ? ex.getCause() : "--") + "] ");
                                    }
                                } catch (Exception ex) {
                                    log("[" + id + "][" + k + "] Exception " + ex);
                                }
                            }
                        } else {
                            boolean retry = true;
                            Iterable<Vertex> vtxs = null;
                            for (int k = 0; k < 100 && retry; k++) try {
                                vtxs = graph.command(new OCommandSQL(query)).execute();
                                break;
                            } catch (ONeedRetryException e) {
                            // RETRY
                            }
                            for (Vertex vtx : vtxs) {
                                if (retry) {
                                    retry = true;
                                    boolean isException = false;
                                    for (int k = 0; k < 100 && retry; k++) {
                                        OrientVertex vtx1 = (OrientVertex) vtx;
                                        try {
                                            vtx1.setProperty("prop5", "prop55");
                                            vtx1.setProperty("updateTime", new Date().toString());
                                            vtx1.setProperty("blob", new byte[1000]);
                                            graph.commit();
                                            if (isException) {
                                            // log("********** [" + id + "][" + k + "] Update success after distributed lock Exception for vertex " +
                                            // vtx1);
                                            }
                                            retry = false;
                                            break;
                                        } catch (OConcurrentModificationException ex) {
                                            vtx1.reload();
                                        } catch (ONeedRetryException ex) {
                                            if (ex instanceof ODistributedRecordLockedException) {
                                                if (k > 20)
                                                    log("*$$$$$$$$$$$$$$ [" + id + "][" + k + "] ODistributedRecordLockedException: [" + ex + "] Cause: [" + (ex.getCause() != null ? ex.getCause() : "--") + "] for vertex " + vtx1);
                                                vtx1.reload();
                                            } else if (ex instanceof ONeedRetryException || ex.getCause() instanceof ONeedRetryException) {
                                                vtx1.reload();
                                            } else {
                                                if (ex.getCause() instanceof ConcurrentModificationException) {
                                                    ex.printStackTrace();
                                                }
                                                log("*$$$$$$$$$$$$$$ [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ? ex.getCause() : "--") + "] for vertex " + vtx1);
                                            }
                                            // log("*** [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ?
                                            // ex.getCause() : "--") + "] for vertex " + vtx1);
                                            isException = true;
                                        } catch (ODistributedException ex) {
                                            if (ex.getCause() instanceof ONeedRetryException) {
                                                vtx1.reload();
                                            } else {
                                                if (ex.getCause() instanceof ConcurrentModificationException) {
                                                    ex.printStackTrace();
                                                }
                                                log("*$$$$$$$$$$$$$$ [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ? ex.getCause() : "--") + "] for vertex " + vtx1);
                                            }
                                            // log("*** [" + id + "][" + k + "] Distributed Exception: [" + ex + "] Cause: [" + (ex.getCause() != null ?
                                            // ex.getCause() : "--") + "] for vertex " + vtx1);
                                            isException = true;
                                        } catch (Exception ex) {
                                            log("[" + id + "][" + k + "] Exception " + ex + " for vertex " + vtx1);
                                        }
                                    }
                                    if (retry) {
                                        log("********** [" + id + "] Failed to update after Exception for vertex " + vtx);
                                    }
                                }
                            }
                        }
                    } finally {
                        graph.shutdown();
                    }
                    operations.incrementAndGet();
                }
            } catch (Exception ex) {
                System.out.println("ID: [" + id + "]********** Exception " + ex + " \n\n");
                ex.printStackTrace();
            } finally {
                log("[" + id + "] Done................>>>>>>>>>>>>>>>>>>");
            }
        }
    };
    return th;
}
Also used : Vertex(com.tinkerpop.blueprints.Vertex) ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) OConcurrentModificationException(com.orientechnologies.orient.core.exception.OConcurrentModificationException) OConcurrentModificationException(com.orientechnologies.orient.core.exception.OConcurrentModificationException) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException) ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) OConcurrentModificationException(com.orientechnologies.orient.core.exception.OConcurrentModificationException) OCommandSQL(com.orientechnologies.orient.core.sql.OCommandSQL) OLocalClusterWrapperStrategy(com.orientechnologies.orient.server.distributed.impl.OLocalClusterWrapperStrategy) ONeedRetryException(com.orientechnologies.common.concur.ONeedRetryException)

Example 5 with ODistributedRecordLockedException

use of com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException in project orientdb by orientechnologies.

the class ConcurrentDistributedUpdateTest method createWriter.

protected Callable<Void> createWriter(final int serverId, final int threadId, final String databaseURL) {
    return new Callable<Void>() {

        @Override
        public Void call() throws Exception {
            final String id = serverId + "." + threadId;
            boolean isRunning = true;
            final OrientBaseGraph graph = new OrientGraph(databaseURL);
            try {
                String query = "select from Test where prop2='v2-1'";
                for (int i = 0; i < 100 && isRunning; i++) {
                    if ((i % 25) == 0) {
                        log("[" + id + "] Records Processed: [" + i + "]");
                    }
                    Iterable<Vertex> vtxs = graph.command(new OCommandSQL(query)).execute();
                    boolean update = true;
                    for (Vertex vtx : vtxs) {
                        if (update) {
                            update = true;
                            for (int k = 0; k < 10 && update; k++) {
                                OrientVertex vtx1 = (OrientVertex) vtx;
                                try {
                                    vtx1.setProperty("prop5", "prop55");
                                    graph.commit();
                                    // log("[" + id + "/" + i + "/" + k + "] OK!\n");
                                    break;
                                } catch (OConcurrentModificationException ex) {
                                    vtx1.reload();
                                } catch (ODistributedRecordLockedException ex) {
                                    log("[" + id + "/" + i + "/" + k + "] Distributed lock Exception " + ex + " for vertex " + vtx1 + " \n");
                                    //                    ex.printStackTrace();
                                    update = false;
                                    //                    isRunning = false;
                                    break;
                                } catch (Exception ex) {
                                    log("[" + id + "/" + i + "/" + k + "] Exception " + ex + " for vertex " + vtx1 + "\n\n");
                                    ex.printStackTrace();
                                    isRunning = false;
                                    break;
                                }
                            }
                            if (!isRunning)
                                break;
                        }
                    }
                }
            } catch (Exception ex) {
                System.out.println("ID: [" + id + "]********** Exception " + ex + " \n\n");
                ex.printStackTrace();
            } finally {
                log("[" + id + "] Done................>>>>>>>>>>>>>>>>>>");
                graph.shutdown();
                runningWriters.countDown();
            }
            Assert.assertTrue(isRunning);
            return null;
        }
    };
}
Also used : OrientVertex(com.tinkerpop.blueprints.impls.orient.OrientVertex) Vertex(com.tinkerpop.blueprints.Vertex) ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) OrientGraph(com.tinkerpop.blueprints.impls.orient.OrientGraph) OrientVertex(com.tinkerpop.blueprints.impls.orient.OrientVertex) OrientBaseGraph(com.tinkerpop.blueprints.impls.orient.OrientBaseGraph) OConcurrentModificationException(com.orientechnologies.orient.core.exception.OConcurrentModificationException) Callable(java.util.concurrent.Callable) ODistributedRecordLockedException(com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException) OConcurrentModificationException(com.orientechnologies.orient.core.exception.OConcurrentModificationException) OCommandSQL(com.orientechnologies.orient.core.sql.OCommandSQL)

Aggregations

ODistributedRecordLockedException (com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException)5 OConcurrentModificationException (com.orientechnologies.orient.core.exception.OConcurrentModificationException)2 OCommandSQL (com.orientechnologies.orient.core.sql.OCommandSQL)2 Vertex (com.tinkerpop.blueprints.Vertex)2 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)1 ODatabaseDocumentInternal (com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)1 OConcurrentCreateException (com.orientechnologies.orient.core.exception.OConcurrentCreateException)1 ORecordId (com.orientechnologies.orient.core.id.ORecordId)1 ORawBuffer (com.orientechnologies.orient.core.storage.ORawBuffer)1 OLocalClusterWrapperStrategy (com.orientechnologies.orient.server.distributed.impl.OLocalClusterWrapperStrategy)1 OAbstractReplicatedTask (com.orientechnologies.orient.server.distributed.task.OAbstractReplicatedTask)1 ODistributedOperationException (com.orientechnologies.orient.server.distributed.task.ODistributedOperationException)1 ORemoteTask (com.orientechnologies.orient.server.distributed.task.ORemoteTask)1 OrientBaseGraph (com.tinkerpop.blueprints.impls.orient.OrientBaseGraph)1 OrientGraph (com.tinkerpop.blueprints.impls.orient.OrientGraph)1 OrientVertex (com.tinkerpop.blueprints.impls.orient.OrientVertex)1 Callable (java.util.concurrent.Callable)1