use of com.orientechnologies.orient.core.storage.ORecordDuplicatedException in project orientdb by orientechnologies.
the class IndexTest method testTransactionUniqueIndexTestWithDotNameOne.
public void testTransactionUniqueIndexTestWithDotNameOne() {
ODatabaseDocumentTx db = new ODatabaseDocumentTx(database.getURL());
db.open("admin", "admin");
if (!db.getMetadata().getSchema().existsClass("TransactionUniqueIndexWithDotTest")) {
final OClass termClass = db.getMetadata().getSchema().createClass("TransactionUniqueIndexWithDotTest", 1, null);
termClass.createProperty("label", OType.STRING).createIndex(INDEX_TYPE.UNIQUE);
db.getMetadata().getSchema().save();
}
ODocument docOne = new ODocument("TransactionUniqueIndexWithDotTest");
docOne.field("label", "A");
docOne.save();
final List<ODocument> resultBeforeCommit = db.query(new OSQLSynchQuery<ODocument>("select from index:TransactionUniqueIndexWithDotTest.label"));
Assert.assertEquals(resultBeforeCommit.size(), 1);
long countClassBefore = db.countClass("TransactionUniqueIndexWithDotTest");
db.begin();
try {
ODocument docTwo = new ODocument("TransactionUniqueIndexWithDotTest");
docTwo.field("label", "A");
docTwo.save();
db.commit();
Assert.fail();
} catch (ORecordDuplicatedException oie) {
}
Assert.assertEquals(((List<ODocument>) db.command(new OCommandSQL("select from TransactionUniqueIndexWithDotTest")).execute()).size(), countClassBefore);
final List<ODocument> resultAfterCommit = db.query(new OSQLSynchQuery<ODocument>("select from index:TransactionUniqueIndexWithDotTest.label"));
Assert.assertEquals(resultAfterCommit.size(), 1);
}
use of com.orientechnologies.orient.core.storage.ORecordDuplicatedException in project orientdb by orientechnologies.
the class OTxTask method execute.
@Override
public Object execute(final ODistributedRequestId requestId, final OServer iServer, ODistributedServerManager iManager, final ODatabaseDocumentInternal database) throws Exception {
ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), DIRECTION.IN, "Executing transaction db=%s (reqId=%s)...", database.getName(), requestId);
ODatabaseRecordThreadLocal.INSTANCE.set(database);
final ODistributedDatabase ddb = iManager.getMessageService().getDatabase(database.getName());
// CREATE A CONTEXT OF TX
reqContext = ddb.registerTxContext(requestId);
final ODistributedConfiguration dCfg = iManager.getDatabaseConfiguration(database.getName());
result = new OTxTaskResult();
if (tasks.size() == 0)
// RETURN AFTER REGISTERED THE CONTEXT
return result;
database.begin();
try {
final OTransactionOptimistic tx = (OTransactionOptimistic) database.getTransaction();
// REGISTER CREATE FIRST TO RESOLVE TEMP RIDS
for (OAbstractRecordReplicatedTask task : tasks) {
if (task instanceof OCreateRecordTask) {
final OCreateRecordTask createRT = (OCreateRecordTask) task;
final ORecordId rid = createRT.getRid();
if (rid != null && rid.isPersistent()) {
if (rid.getRecord() != null)
// ALREADY CREATED: SKIP REGISTERING IN TX
continue;
}
final int clId = createRT.clusterId > -1 ? createRT.clusterId : createRT.getRid().isValid() ? createRT.getRid().getClusterId() : -1;
final String clusterName = clId > -1 ? database.getClusterNameById(clId) : null;
if (dCfg.isServerContainingCluster(iManager.getLocalNodeName(), clusterName))
tx.addRecord(createRT.getRecord(), ORecordOperation.CREATED, clusterName);
}
}
final List<ORecordId> rids2Lock = new ArrayList<ORecordId>();
// LOCK ALL THE RECORDS FIRST (ORDERED TO AVOID DEADLOCK)
for (OAbstractRecordReplicatedTask task : tasks) rids2Lock.add(task.getRid());
Collections.sort(rids2Lock);
for (ORecordId rid : rids2Lock) reqContext.lock(rid, getRecordLock());
for (OAbstractRecordReplicatedTask task : tasks) {
final Object taskResult;
// CHECK LOCAL CLUSTER IS AVAILABLE ON CURRENT SERVER
if (!task.checkForClusterAvailability(iManager.getLocalNodeName(), dCfg))
// SKIP EXECUTION BECAUSE THE CLUSTER IS NOT ON LOCAL NODE: THIS CAN HAPPENS IN CASE OF DISTRIBUTED TX WITH SHARDING
taskResult = NON_LOCAL_CLUSTER;
else {
task.setLockRecords(false);
task.checkRecordExists();
taskResult = task.execute(requestId, iServer, iManager, database);
reqContext.addUndoTask(task.getUndoTask(requestId));
}
result.results.add(taskResult);
}
database.commit();
// SEND BACK CHANGED VALUE TO UPDATE
for (int i = 0; i < result.results.size(); ++i) {
final Object currentResult = result.results.get(i);
if (currentResult == NON_LOCAL_CLUSTER)
// SKIP IT
continue;
final OAbstractRecordReplicatedTask task = tasks.get(i);
if (task instanceof OCreateRecordTask) {
// SEND RID + VERSION
final OCreateRecordTask t = (OCreateRecordTask) task;
result.results.set(i, new OPlaceholder(t.getRecord()));
} else if (task instanceof OUpdateRecordTask) {
// SEND VERSION
result.results.set(i, task.getRecord().getVersion());
}
}
return result;
} catch (Throwable e) {
// if (e instanceof ODistributedRecordLockedException)
// ddb.dumpLocks();
ODistributedServerLog.debug(this, iManager.getLocalNodeName(), getNodeSource(), DIRECTION.IN, "Rolling back transaction on local server db=%s (reqId=%s error=%s)...", database.getName(), requestId, e);
database.rollback();
// ddb.popTxContext(requestId);
reqContext.unlock();
if (!(e instanceof ONeedRetryException || e instanceof OTransactionException || e instanceof ORecordDuplicatedException || e instanceof ORecordNotFoundException))
// DUMP ONLY GENERIC EXCEPTIONS
ODistributedServerLog.info(this, getNodeSource(), null, DIRECTION.NONE, "Error on distributed transaction commit", e);
return e;
}
}
use of com.orientechnologies.orient.core.storage.ORecordDuplicatedException in project orientdb by orientechnologies.
the class DistributedConfigReloadTest method startCreateDeleteVertex.
private Runnable startCreateDeleteVertex(final int id, final OrientGraphFactory graphFactory, final String className) {
Runnable th = new Runnable() {
@Override
public void run() {
log("Starting runnable to create index " + className);
long st = System.currentTimeMillis();
OrientGraph graph = graphFactory.getTx();
boolean isSelectSuccessful = true;
try {
boolean isRunning = true;
for (int j = 0; j < 1000000; j++) {
isSelectSuccessful = true;
String sql = "SELECT FROM " + className;
int deleteErrorCounter = 0;
try {
graph.command(new OCommandSQL(sql)).execute();
Iterable<Vertex> vtxs = graph.command(new OCommandSQL(sql)).execute();
for (Vertex vtx : vtxs) {
boolean needRetry = true;
for (int i = 0; i < 10 && needRetry; i++) {
try {
vtx.remove();
graph.commit();
needRetry = false;
} catch (ONeedRetryException ex) {
try {
((OrientElement) vtx).reload();
} catch (ORecordNotFoundException e) {
// BY LUCA
log("[" + id + "] Caught [" + e + "] during reload because the record was already deleted, no errors just go ahead");
}
} catch (ORecordNotFoundException e) {
// BY LUCA
log("[" + id + "] Caught [" + e + "] because the record was already deleted, no errors just go ahead");
} catch (Exception ex) {
log("[" + j + "] Failed to delete vertex [" + className + "] Vertex: [" + vtx + "] Property 1: [" + vtx.getProperty("property1") + "] Error: [" + ex + "]");
deleteErrorCounter++;
needRetry = false;
}
}
}
log(" [" + id + "] Delete vertex : [" + j + "] [" + className + "]");
} catch (Exception ex) {
log("***************** [" + id + "] Failed to select vertex [" + className + "][" + ex + "]");
isSelectSuccessful = false;
}
if (isSelectSuccessful) {
graph.command(new OCommandSQL(sql)).execute();
Iterable<Vertex> vtxs = graph.command(new OCommandSQL(sql)).execute();
ArrayList<String> vtxList = new ArrayList();
for (Vertex vtx : vtxs) {
vtxList.add(vtx.toString());
}
if (vtxList.size() > 0) {
log("########## [" + id + "] Records present after delete vertex [" + className + "] Error on delete [" + deleteErrorCounter + "] List: " + vtxList + "");
} else {
log("########## [" + id + "] Records removed after delete vertex [" + className + "] Error on delete [" + deleteErrorCounter + "]");
}
boolean showException = true;
int counter = 0;
for (int i = 1; i < 2000 && isRunning; i++) {
if ((i % 2000) == 0) {
long et = System.currentTimeMillis();
log(" [" + id + "] Total Records Processed: [" + i + "] Time taken for [2000] records: [" + (et - st) / 2000 + "] seconds");
st = System.currentTimeMillis();
}
Vertex vertex = graph.addVertex("class:" + className);
try {
vertex.setProperty("property1", "value-" + id + "-" + i);
vertex.setProperty("property2", "value2-" + (System.currentTimeMillis() + "-" + i));
vertex.setProperty("property3", "value3-" + i);
vertex.setProperty("property4", "value4-1");
vertex.setProperty("prop-6", "value6-" + i);
vertex.setProperty("prop-7", "value7-" + i);
vertex.setProperty("prop-8", "value7-1");
vertex.setProperty("prop-9", "value7-1");
vertex.setProperty("prop-10", "value7-1");
vertex.setProperty("prop11", "value7-1");
vertex.setProperty("prop12", "value7-1");
vertex.setProperty("prop13", "value7-1");
vertex.setProperty("prop14", System.currentTimeMillis());
vertex.setProperty("prop15", System.currentTimeMillis());
graph.commit();
} catch (ONeedRetryException ex) {
if (ex instanceof ONeedRetryException || ex.getCause() instanceof ONeedRetryException) {
log("[" + id + "] OrientDB Retry Exception [" + ex + "]");
} else {
log("[" + id + "] OrientDB Exception [" + ex + "]");
}
if (!(ex instanceof ODistributedConfigurationChangedException || ex.getCause() instanceof ODistributedConfigurationChangedException)) {
//reloadVertex(vertex, ex);
} else {
log("[" + id + "] ODistributedConfigurationChangedException {} while updating vertex " + vertex);
}
} catch (ORecordDuplicatedException ex) {
// BY LUCA
log("[" + id + "] Caught [" + ex + "], no errors just go ahead");
} catch (ODistributedException ex) {
if (ex.getCause() instanceof ONeedRetryException) {
log("[" + id + "] OrientDB Retry Exception [" + ex + "]");
} else {
log("[" + id + "] OrientDB Exception [" + ex + "]");
}
if (!(ex.getCause() instanceof ODistributedConfigurationChangedException)) {
//reloadVertex(vertex, ex);
} else {
log("[" + id + "] ODistributedConfigurationChangedException {} while updating vertex " + vertex);
}
} catch (Exception ex) {
if (showException) {
log("[" + id + "] Failed to create record Exception [" + ex + "]");
showException = false;
counter++;
}
}
}
log("************ [" + id + "] Total number of errors: [" + counter + "] Delete error counter:[" + deleteErrorCounter + "]");
} else {
log("##################### [" + id + "] Select failed. Skipping create..");
}
}
} finally {
graph.shutdown();
}
}
};
return th;
}
use of com.orientechnologies.orient.core.storage.ORecordDuplicatedException in project orientdb by orientechnologies.
the class OIncrementalServerSync method importDelta.
/**
* Deleted records are written in output stream first, then created/updated records. All records are sorted by record id.
* <p>
* Each record in output stream is written using following format:
* <ol>
* <li>Record's cluster id - 4 bytes</li>
* <li>Record's cluster position - 8 bytes</li>
* <li>Delete flag, 1 if record is deleted - 1 byte</li>
* <li>Record version , only if record is not deleted - 4 bytes</li>
* <li>Record type, only if record is not deleted - 1 byte</li>
* <li>Length of binary presentation of record, only if record is not deleted - 4 bytes</li>
* <li>Binary presentation of the record, only if record is not deleted - length of content is provided in above entity</li>
* </ol>
*/
public void importDelta(final OServer serverInstance, final ODatabaseDocumentInternal db, final FileInputStream in, final String iNode) throws IOException {
final String nodeName = serverInstance.getDistributedManager().getLocalNodeName();
try {
serverInstance.openDatabase(db);
OScenarioThreadLocal.executeAsDistributed(new Callable<Object>() {
@Override
public Object call() throws Exception {
db.activateOnCurrentThread();
long totalRecords = 0;
long totalCreated = 0;
long totalUpdated = 0;
long totalDeleted = 0;
long totalHoles = 0;
long totalSkipped = 0;
ODistributedServerLog.info(this, nodeName, iNode, DIRECTION.IN, "Started import of delta for database '" + db.getName() + "'");
long lastLap = System.currentTimeMillis();
// final GZIPInputStream gzipInput = new GZIPInputStream(in);
try {
final DataInputStream input = new DataInputStream(in);
try {
final long records = input.readLong();
for (long i = 0; i < records; ++i) {
final int clusterId = input.readInt();
final long clusterPos = input.readLong();
final boolean deleted = input.readBoolean();
final ORecordId rid = new ORecordId(clusterId, clusterPos);
totalRecords++;
final OPaginatedCluster cluster = (OPaginatedCluster) db.getStorage().getUnderlying().getClusterById(rid.getClusterId());
final OPaginatedCluster.RECORD_STATUS recordStatus = cluster.getRecordStatus(rid.getClusterPosition());
ORecord newRecord = null;
if (deleted) {
ODistributedServerLog.debug(this, nodeName, iNode, DIRECTION.IN, "DELTA <- deleting %s", rid);
switch(recordStatus) {
case REMOVED:
// SKIP IT
totalSkipped++;
continue;
case ALLOCATED:
case PRESENT:
// DELETE IT
db.delete(rid);
break;
case NOT_EXISTENT:
totalSkipped++;
break;
}
totalDeleted++;
} else {
final int recordVersion = input.readInt();
final int recordType = input.readByte();
final int recordSize = input.readInt();
final byte[] recordContent = new byte[recordSize];
input.read(recordContent);
switch(recordStatus) {
case REMOVED:
// SKIP IT
totalSkipped++;
continue;
case ALLOCATED:
case PRESENT:
// UPDATE IT
newRecord = Orient.instance().getRecordFactoryManager().newInstance((byte) recordType);
ORecordInternal.fill(newRecord, rid, ORecordVersionHelper.setRollbackMode(recordVersion), recordContent, true);
final ORecord loadedRecord = rid.getRecord();
if (loadedRecord instanceof ODocument) {
// APPLY CHANGES FIELD BY FIELD TO MARK DIRTY FIELDS FOR INDEXES/HOOKS
ODocument loadedDocument = (ODocument) loadedRecord;
loadedDocument.merge((ODocument) newRecord, false, false);
ORecordInternal.setVersion(loadedRecord, ORecordVersionHelper.setRollbackMode(recordVersion));
loadedDocument.setDirty();
newRecord = loadedDocument;
}
// SAVE THE UPDATE RECORD
newRecord.save();
ODistributedServerLog.debug(this, nodeName, iNode, DIRECTION.IN, "DELTA <- updating rid=%s type=%d size=%d v=%d content=%s", rid, recordType, recordSize, recordVersion, newRecord);
totalUpdated++;
break;
case NOT_EXISTENT:
// CREATE AND DELETE RECORD IF NEEDED
do {
newRecord = Orient.instance().getRecordFactoryManager().newInstance((byte) recordType);
ORecordInternal.fill(newRecord, new ORecordId(rid.getClusterId(), -1), recordVersion - 1, recordContent, true);
try {
newRecord.save();
} catch (ORecordNotFoundException e) {
ODistributedServerLog.info(this, nodeName, iNode, DIRECTION.IN, "DELTA <- error on saving record (not found) rid=%s type=%d size=%d v=%d content=%s", rid, recordType, recordSize, recordVersion, newRecord);
} catch (ORecordDuplicatedException e) {
ODistributedServerLog.info(this, nodeName, iNode, DIRECTION.IN, "DELTA <- error on saving record (duplicated %s) rid=%s type=%d size=%d v=%d content=%s", e.getRid(), rid, recordType, recordSize, recordVersion, newRecord);
// throw OException.wrapException(
// new ODistributedDatabaseDeltaSyncException("Error on delta sync: found duplicated record " + rid), e);
final ORecord duplicatedRecord = db.load(e.getRid(), null, true);
if (duplicatedRecord == null) {
// RECORD REMOVED: THE INDEX IS DIRTY, FIX THE DIRTY INDEX
final ODocument doc = (ODocument) newRecord;
final OIndex<?> index = db.getMetadata().getIndexManager().getIndex(e.getIndexName());
final List<String> fields = index.getDefinition().getFields();
final List<Object> values = new ArrayList<Object>(fields.size());
for (String f : fields) {
values.add(doc.field(f));
}
final Object keyValue = index.getDefinition().createValue(values);
index.remove(keyValue, e.getRid());
// RESAVE THE RECORD
newRecord.save();
} else
break;
}
if (newRecord.getIdentity().getClusterPosition() < clusterPos) {
// DELETE THE RECORD TO CREATE A HOLE
ODistributedServerLog.debug(this, nodeName, iNode, DIRECTION.IN, "DELTA <- creating hole rid=%s", newRecord.getIdentity());
newRecord.delete();
totalHoles++;
}
} while (newRecord.getIdentity().getClusterPosition() < clusterPos);
ODistributedServerLog.debug(this, nodeName, iNode, DIRECTION.IN, "DELTA <- creating rid=%s type=%d size=%d v=%d content=%s", rid, recordType, recordSize, recordVersion, newRecord);
totalCreated++;
break;
}
if (newRecord.getIdentity().isPersistent() && !newRecord.getIdentity().equals(rid))
throw new ODistributedDatabaseDeltaSyncException("Error on synchronization of records, rids are different: saved " + newRecord.getIdentity() + ", but it should be " + rid);
}
final long now = System.currentTimeMillis();
if (now - lastLap > 2000) {
// DUMP STATS EVERY SECOND
ODistributedServerLog.info(this, nodeName, iNode, DIRECTION.IN, "- %,d total entries: %,d created, %,d updated, %,d deleted, %,d holes, %,d skipped...", totalRecords, totalCreated, totalUpdated, totalDeleted, totalHoles, totalSkipped);
lastLap = now;
}
}
db.getMetadata().reload();
} finally {
input.close();
}
} catch (Exception e) {
ODistributedServerLog.error(this, nodeName, iNode, DIRECTION.IN, "Error on installing database delta '%s' on local server", e, db.getName());
throw OException.wrapException(new ODistributedException("Error on installing database delta '" + db.getName() + "' on local server"), e);
} finally {
// gzipInput.close();
}
ODistributedServerLog.info(this, nodeName, iNode, DIRECTION.IN, "Installed database delta for '%s'. %d total entries: %d created, %d updated, %d deleted, %d holes, %,d skipped", db.getName(), totalRecords, totalCreated, totalUpdated, totalDeleted, totalHoles, totalSkipped);
return null;
}
});
db.activateOnCurrentThread();
} catch (Exception e) {
// FORCE FULL DATABASE SYNC
ODistributedServerLog.error(this, nodeName, iNode, DIRECTION.IN, "Error while applying changes of database delta sync on '%s': forcing full database sync...", e, db.getName());
throw OException.wrapException(new ODistributedDatabaseDeltaSyncException("Error while applying changes of database delta sync on '" + db.getName() + "': forcing full database sync..."), e);
}
}
use of com.orientechnologies.orient.core.storage.ORecordDuplicatedException in project orientdb by orientechnologies.
the class ClassIndexManagerTest method testPropertiesCheckUniqueIndexDubKeysCreate.
public void testPropertiesCheckUniqueIndexDubKeysCreate() {
final ODocument docOne = new ODocument("classIndexManagerTestClass");
final ODocument docTwo = new ODocument("classIndexManagerTestClass");
docOne.field("prop1", "a");
docOne.save();
boolean exceptionThrown = false;
try {
docTwo.field("prop1", "a");
docTwo.save();
} catch (ORecordDuplicatedException e) {
exceptionThrown = true;
}
Assert.assertTrue(exceptionThrown);
}
Aggregations