Search in sources :

Example 6 with ORecordOperation

use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.

the class OTransactionOptimistic method invokeCallbacks.

private void invokeCallbacks() {
    if (recordCreatedCallback != null || recordUpdatedCallback != null) {
        for (ORecordOperation operation : allEntries.values()) {
            final ORecord record = operation.getRecord();
            final ORID identity = record.getIdentity();
            if (operation.type == ORecordOperation.CREATED && recordCreatedCallback != null)
                recordCreatedCallback.call(new ORecordId(identity), identity.getClusterPosition());
            else if (operation.type == ORecordOperation.UPDATED && recordUpdatedCallback != null)
                recordUpdatedCallback.call(new ORecordId(identity), record.getVersion());
        }
    }
}
Also used : ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) ORecord(com.orientechnologies.orient.core.record.ORecord) ORID(com.orientechnologies.orient.core.id.ORID) ORecordId(com.orientechnologies.orient.core.id.ORecordId)

Example 7 with ORecordOperation

use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.

the class OTransactionRealAbstract method updateIdentityAfterCommit.

public void updateIdentityAfterCommit(final ORID oldRid, final ORID newRid) {
    if (oldRid.equals(newRid))
        // NO CHANGE, IGNORE IT
        return;
    // XXX: Identity update may mutate the index keys, so we have to identify and reinsert potentially affected index keys to keep
    // the OTransactionIndexChanges.changesPerKey in a consistent state.
    final List<KeyChangesUpdateRecord> keyRecordsToReinsert = new ArrayList<KeyChangesUpdateRecord>();
    final OIndexManager indexManager = getDatabase().getMetadata().getIndexManager();
    for (Entry<String, OTransactionIndexChanges> entry : indexEntries.entrySet()) {
        final OIndex<?> index = indexManager.getIndex(entry.getKey());
        if (index == null)
            throw new OTransactionException("Cannot find index '" + entry.getValue() + "' while committing transaction");
        final Dependency[] fieldRidDependencies = getIndexFieldRidDependencies(index);
        if (!isIndexMayDependOnRids(fieldRidDependencies))
            continue;
        final OTransactionIndexChanges indexChanges = entry.getValue();
        for (final Iterator<OTransactionIndexChangesPerKey> iterator = indexChanges.changesPerKey.values().iterator(); iterator.hasNext(); ) {
            final OTransactionIndexChangesPerKey keyChanges = iterator.next();
            if (isIndexKeyMayDependOnRid(keyChanges.key, oldRid, fieldRidDependencies)) {
                keyRecordsToReinsert.add(new KeyChangesUpdateRecord(keyChanges, indexChanges));
                iterator.remove();
            }
        }
    }
    // Update the identity.
    final ORecordOperation rec = getRecordEntry(oldRid);
    if (rec != null) {
        updatedRids.put(newRid.copy(), oldRid.copy());
        if (!rec.getRecord().getIdentity().equals(newRid)) {
            ORecordInternal.onBeforeIdentityChanged(rec.getRecord());
            final ORecordId recordId = (ORecordId) rec.getRecord().getIdentity();
            if (recordId == null) {
                ORecordInternal.setIdentity(rec.getRecord(), new ORecordId(newRid));
            } else {
                recordId.setClusterPosition(newRid.getClusterPosition());
                recordId.setClusterId(newRid.getClusterId());
            }
            ORecordInternal.onAfterIdentityChanged(rec.getRecord());
        }
    }
    for (KeyChangesUpdateRecord record : keyRecordsToReinsert) record.indexChanges.changesPerKey.put(record.keyChanges.key, record.keyChanges);
    // Update the indexes.
    final List<OTransactionRecordIndexOperation> transactionIndexOperations = recordIndexOperations.get(translateRid(oldRid));
    if (transactionIndexOperations != null) {
        for (final OTransactionRecordIndexOperation indexOperation : transactionIndexOperations) {
            OTransactionIndexChanges indexEntryChanges = indexEntries.get(indexOperation.index);
            if (indexEntryChanges == null)
                continue;
            final OTransactionIndexChangesPerKey keyChanges = indexEntryChanges.changesPerKey.get(indexOperation.key);
            if (keyChanges != null)
                updateChangesIdentity(oldRid, newRid, keyChanges);
        }
    }
}
Also used : ORecordId(com.orientechnologies.orient.core.id.ORecordId) OIndexManager(com.orientechnologies.orient.core.index.OIndexManager) ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) OTransactionException(com.orientechnologies.orient.core.exception.OTransactionException)

Example 8 with ORecordOperation

use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.

the class OAbstractPaginatedStorage method commit.

public List<ORecordOperation> commit(final OTransaction clientTx, Runnable callback) {
    checkOpeness();
    checkLowDiskSpaceFullCheckpointRequestsAndBackgroundDataFlushExceptions();
    txBegun.incrementAndGet();
    final ODatabaseDocumentInternal databaseRecord = (ODatabaseDocumentInternal) clientTx.getDatabase();
    final OIndexManagerProxy indexManager = databaseRecord.getMetadata().getIndexManager();
    final TreeMap<String, OTransactionIndexChanges> indexesToCommit = getSortedIndexEntries(clientTx);
    final Map<ORecordOperation, Integer> clusterOverrides = new IdentityHashMap<ORecordOperation, Integer>();
    databaseRecord.getMetadata().makeThreadLocalSchemaSnapshot();
    if (OLogManager.instance().isDebugEnabled())
        OLogManager.instance().debug(this, "%d Committing transaction %d on database '%s' (items=%d)...", Thread.currentThread().getId(), clientTx.getId(), databaseRecord.getName(), clientTx.getEntryCount());
    final Iterable<ORecordOperation> entries = (Iterable<ORecordOperation>) clientTx.getAllRecordEntries();
    final TreeMap<Integer, OCluster> clustersToLock = new TreeMap<Integer, OCluster>();
    final Set<ORecordOperation> newRecords = new TreeSet<ORecordOperation>(new Comparator<ORecordOperation>() {

        @Override
        public int compare(final ORecordOperation o1, final ORecordOperation o2) {
            return o1.getRecord().getIdentity().compareTo(o2.getRecord().getIdentity());
        }
    });
    for (ORecordOperation txEntry : entries) {
        if (txEntry.type == ORecordOperation.CREATED || txEntry.type == ORecordOperation.UPDATED) {
            final ORecord record = txEntry.getRecord();
            if (record instanceof ODocument)
                ((ODocument) record).validate();
        }
        if (txEntry.type == ORecordOperation.UPDATED || txEntry.type == ORecordOperation.DELETED) {
            final int clusterId = txEntry.getRecord().getIdentity().getClusterId();
            clustersToLock.put(clusterId, getClusterById(clusterId));
        } else if (txEntry.type == ORecordOperation.CREATED) {
            newRecords.add(txEntry);
            final ORecord record = txEntry.getRecord();
            final ORID rid = record.getIdentity();
            int clusterId = rid.getClusterId();
            if (record.isDirty() && clusterId == ORID.CLUSTER_ID_INVALID && record instanceof ODocument) {
                // TRY TO FIX CLUSTER ID TO THE DEFAULT CLUSTER ID DEFINED IN SCHEMA CLASS
                final OImmutableClass class_ = ODocumentInternal.getImmutableSchemaClass(((ODocument) record));
                if (class_ != null) {
                    clusterId = class_.getClusterForNewInstance((ODocument) record);
                    clusterOverrides.put(txEntry, clusterId);
                }
            }
            clustersToLock.put(clusterId, getClusterById(clusterId));
        }
    }
    final List<ORecordOperation> result = new ArrayList<ORecordOperation>();
    final List<Lock[]> indexKeyLockList = new ArrayList<Lock[]>(indexesToCommit.size());
    stateLock.acquireReadLock();
    try {
        try {
            try {
                checkOpeness();
                lockIndexKeys(indexManager, indexesToCommit, indexKeyLockList);
                makeStorageDirty();
                startStorageTx(clientTx);
                lockClusters(clustersToLock);
                lockRidBags(clustersToLock, indexesToCommit);
                lockIndexes(indexesToCommit);
                Map<ORecordOperation, OPhysicalPosition> positions = new IdentityHashMap<ORecordOperation, OPhysicalPosition>();
                for (ORecordOperation txEntry : newRecords) {
                    ORecord rec = txEntry.getRecord();
                    if (rec.isDirty()) {
                        ORecordId rid = (ORecordId) rec.getIdentity().copy();
                        ORecordId oldRID = rid.copy();
                        final Integer clusterOverride = clusterOverrides.get(txEntry);
                        final int clusterId = clusterOverride == null ? rid.getClusterId() : clusterOverride;
                        final OCluster cluster = getClusterById(clusterId);
                        OPhysicalPosition ppos = cluster.allocatePosition(ORecordInternal.getRecordType(rec));
                        rid.setClusterId(cluster.getId());
                        if (rid.getClusterPosition() > -1) {
                            // RECORD HAVING A HIGHER CLUSTER POSITION
                            while (rid.getClusterPosition() > ppos.clusterPosition) {
                                ppos = cluster.allocatePosition(ORecordInternal.getRecordType(rec));
                            }
                            if (rid.getClusterPosition() != ppos.clusterPosition)
                                throw new OConcurrentCreateException(rid, new ORecordId(rid.getClusterId(), ppos.clusterPosition));
                        }
                        positions.put(txEntry, ppos);
                        rid.setClusterPosition(ppos.clusterPosition);
                        clientTx.updateIdentityAfterCommit(oldRID, rid);
                    }
                }
                for (ORecordOperation txEntry : entries) {
                    commitEntry(txEntry, positions.get(txEntry));
                    result.add(txEntry);
                }
                commitIndexes(indexesToCommit);
                endStorageTx();
                OTransactionAbstract.updateCacheFromEntries(clientTx, entries, true);
                txCommit.incrementAndGet();
            } catch (IOException ioe) {
                makeRollback(clientTx, ioe);
            } catch (RuntimeException e) {
                makeRollback(clientTx, e);
            } finally {
                unlockIndexKeys(indexesToCommit, indexKeyLockList);
                transaction.set(null);
            }
        } finally {
            databaseRecord.getMetadata().clearThreadLocalSchemaSnapshot();
        }
    } finally {
        stateLock.releaseReadLock();
    }
    if (OLogManager.instance().isDebugEnabled())
        OLogManager.instance().debug(this, "%d Committed transaction %d on database '%s' (result=%s)", Thread.currentThread().getId(), clientTx.getId(), databaseRecord.getName(), result);
    return result;
}
Also used : ODatabaseDocumentInternal(com.orientechnologies.orient.core.db.ODatabaseDocumentInternal) ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) ORID(com.orientechnologies.orient.core.id.ORID) ODocument(com.orientechnologies.orient.core.record.impl.ODocument) OImmutableClass(com.orientechnologies.orient.core.metadata.schema.OImmutableClass) ORecordId(com.orientechnologies.orient.core.id.ORecordId) Lock(java.util.concurrent.locks.Lock) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ORecord(com.orientechnologies.orient.core.record.ORecord)

Example 9 with ORecordOperation

use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.

the class OLiveQueryTest method testLiveInsert.

@Test
public void testLiveInsert() throws InterruptedException {
    ODatabaseDocumentTx db = new ODatabaseDocumentTx("memory:OLiveQueryTest");
    db.activateOnCurrentThread();
    db.create();
    try {
        db.getMetadata().getSchema().createClass("test");
        db.getMetadata().getSchema().createClass("test2");
        MyLiveQueryListener listener = new MyLiveQueryListener();
        OResultSet<ODocument> tokens = db.query(new OLiveQuery<ODocument>("live select from test", listener));
        Assert.assertEquals(tokens.size(), 1);
        ODocument tokenDoc = tokens.get(0);
        Integer token = tokenDoc.field("token");
        Assert.assertNotNull(token);
        db.command(new OCommandSQL("insert into test set name = 'foo', surname = 'bar'")).execute();
        db.command(new OCommandSQL("insert into test set name = 'foo', surname = 'baz'")).execute();
        db.command(new OCommandSQL("insert into test2 set name = 'foo'")).execute();
        latch.await(1, TimeUnit.MINUTES);
        db.command(new OCommandSQL("live unsubscribe " + token)).execute();
        db.command(new OCommandSQL("insert into test set name = 'foo', surname = 'bax'")).execute();
        db.command(new OCommandSQL("insert into test2 set name = 'foo'"));
        db.command(new OCommandSQL("insert into test set name = 'foo', surname = 'baz'")).execute();
        Assert.assertEquals(listener.ops.size(), 2);
        for (ORecordOperation doc : listener.ops) {
            Assert.assertEquals(doc.type, ORecordOperation.CREATED);
            Assert.assertEquals(((ODocument) doc.record).field("name"), "foo");
        }
    } finally {
        db.drop();
    }
}
Also used : ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) ODatabaseDocumentTx(com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx) ODocument(com.orientechnologies.orient.core.record.impl.ODocument) Test(org.testng.annotations.Test)

Example 10 with ORecordOperation

use of com.orientechnologies.orient.core.db.record.ORecordOperation in project orientdb by orientechnologies.

the class OLiveCommandResultListenerTest method testSimpleMessageSend.

@Test
public void testSimpleMessageSend() throws IOException {
    OLiveCommandResultListener listener = new OLiveCommandResultListener(server, connection, 20, new TestResultListener());
    ORecordOperation op = new ORecordOperation(new ODocument(), ORecordOperation.CREATED);
    listener.onLiveResult(10, op);
    Mockito.verify(channelBinary, VerificationModeFactory.atLeastOnce()).writeBytes(Mockito.any(byte[].class));
}
Also used : ORecordOperation(com.orientechnologies.orient.core.db.record.ORecordOperation) OLiveCommandResultListener(com.orientechnologies.orient.server.network.protocol.binary.OLiveCommandResultListener) ODocument(com.orientechnologies.orient.core.record.impl.ODocument) Test(org.junit.Test)

Aggregations

ORecordOperation (com.orientechnologies.orient.core.db.record.ORecordOperation)27 ODocument (com.orientechnologies.orient.core.record.impl.ODocument)13 ORecordId (com.orientechnologies.orient.core.id.ORecordId)11 ORecord (com.orientechnologies.orient.core.record.ORecord)11 OException (com.orientechnologies.common.exception.OException)7 IOException (java.io.IOException)7 OLiveResultListener (com.orientechnologies.orient.core.sql.query.OLiveResultListener)5 Test (org.testng.annotations.Test)5 OTransactionException (com.orientechnologies.orient.core.exception.OTransactionException)4 ORID (com.orientechnologies.orient.core.id.ORID)4 ONeedRetryException (com.orientechnologies.common.concur.ONeedRetryException)3 ODatabaseDocumentInternal (com.orientechnologies.orient.core.db.ODatabaseDocumentInternal)3 ODatabaseDocument (com.orientechnologies.orient.core.db.document.ODatabaseDocument)3 ODatabaseDocumentTx (com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx)3 ORecordNotFoundException (com.orientechnologies.orient.core.exception.ORecordNotFoundException)3 OCommandSQL (com.orientechnologies.orient.core.sql.OCommandSQL)3 CountDownLatch (java.util.concurrent.CountDownLatch)3 Test (org.junit.Test)3 ODatabaseException (com.orientechnologies.orient.core.exception.ODatabaseException)2 OStorageException (com.orientechnologies.orient.core.exception.OStorageException)2