use of com.orientechnologies.orient.core.exception.OTransactionException in project orientdb by orientechnologies.
the class OCommandExecutorScript method executeSQLScript.
protected Object executeSQLScript(final String iText, final ODatabaseDocument db) throws IOException {
Object lastResult = null;
int maxRetry = 1;
context.setVariable("transactionRetries", 0);
context.setVariable("parentQuery", this);
for (int retry = 1; retry <= maxRetry; retry++) {
try {
try {
int txBegunAtLine = -1;
int txBegunAtPart = -1;
lastResult = null;
int nestedLevel = 0;
int skippingScriptsAtNestedLevel = -1;
final BufferedReader reader = new BufferedReader(new StringReader(iText));
int line = 0;
int linePart = 0;
String lastLine;
boolean txBegun = false;
for (; line < txBegunAtLine; ++line) // SKIP PREVIOUS COMMAND AND JUMP TO THE BEGIN IF ANY
reader.readLine();
for (; (lastLine = reader.readLine()) != null; ++line) {
lastLine = lastLine.trim();
// this block is here (and not below, with the other conditions)
// just because of the smartSprit() that does not parse correctly a single bracket
// final List<String> lineParts = OStringSerializerHelper.smartSplit(lastLine, ';', true);
final List<String> lineParts = splitBySemicolon(lastLine);
if (line == txBegunAtLine)
// SKIP PREVIOUS COMMAND PART AND JUMP TO THE BEGIN IF ANY
linePart = txBegunAtPart;
else
linePart = 0;
boolean breakReturn = false;
for (; linePart < lineParts.size(); ++linePart) {
final String lastCommand = lineParts.get(linePart);
if (isIfCondition(lastCommand)) {
nestedLevel++;
if (skippingScriptsAtNestedLevel >= 0) {
// I'm in an (outer) IF that did not match the condition
continue;
}
boolean ifResult = evaluateIfCondition(lastCommand);
if (!ifResult) {
// if does not match the condition, skip all the inner statements
skippingScriptsAtNestedLevel = nestedLevel;
}
continue;
} else if (lastCommand.equals("}")) {
nestedLevel--;
if (skippingScriptsAtNestedLevel > nestedLevel) {
skippingScriptsAtNestedLevel = -1;
}
continue;
} else if (skippingScriptsAtNestedLevel >= 0) {
// I'm in an IF that did not match the condition
continue;
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "let ")) {
lastResult = executeLet(lastCommand, db);
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "begin")) {
if (txBegun)
throw new OCommandSQLParsingException("Transaction already begun");
if (db.getTransaction().isActive())
// COMMIT ANY ACTIVE TX
db.commit();
txBegun = true;
txBegunAtLine = line;
txBegunAtPart = linePart;
db.begin();
if (lastCommand.length() > "begin ".length()) {
String next = lastCommand.substring("begin ".length()).trim();
if (OStringSerializerHelper.startsWithIgnoreCase(next, "isolation ")) {
next = next.substring("isolation ".length()).trim();
db.getTransaction().setIsolationLevel(OTransaction.ISOLATION_LEVEL.valueOf(next.toUpperCase()));
}
}
} else if ("rollback".equalsIgnoreCase(lastCommand)) {
if (!txBegun)
throw new OCommandSQLParsingException("Transaction not begun");
db.rollback();
txBegun = false;
txBegunAtLine = -1;
txBegunAtPart = -1;
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "commit")) {
if (txBegunAtLine < 0)
throw new OCommandSQLParsingException("Transaction not begun");
if (retry == 1 && lastCommand.length() > "commit ".length()) {
// FIRST CYCLE: PARSE RETRY TIMES OVERWRITING DEFAULT = 1
String next = lastCommand.substring("commit ".length()).trim();
if (OStringSerializerHelper.startsWithIgnoreCase(next, "retry ")) {
next = next.substring("retry ".length()).trim();
maxRetry = Integer.parseInt(next);
}
}
db.commit();
txBegun = false;
txBegunAtLine = -1;
txBegunAtPart = -1;
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "sleep ")) {
executeSleep(lastCommand);
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "console.log ")) {
executeConsoleLog(lastCommand, db);
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "console.output ")) {
executeConsoleOutput(lastCommand, db);
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "console.error ")) {
executeConsoleError(lastCommand, db);
} else if (OStringSerializerHelper.startsWithIgnoreCase(lastCommand, "return ")) {
lastResult = getValue(lastCommand.substring("return ".length()), db);
// END OF SCRIPT
breakReturn = true;
break;
} else if (lastCommand != null && lastCommand.length() > 0)
lastResult = executeCommand(lastCommand, db);
}
if (breakReturn) {
break;
}
}
} catch (RuntimeException ex) {
if (db.getTransaction().isActive())
db.rollback();
throw ex;
}
// COMPLETED
break;
} catch (OTransactionException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
getDatabase().getLocalCache().clear();
if (retry >= maxRetry)
throw e;
waitForNextRetry();
} catch (ORecordDuplicatedException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
getDatabase().getLocalCache().clear();
if (retry >= maxRetry)
throw e;
waitForNextRetry();
} catch (ORecordNotFoundException e) {
// THIS CASE IS ON UPSERT
context.setVariable("retries", retry);
getDatabase().getLocalCache().clear();
if (retry >= maxRetry)
throw e;
} catch (ONeedRetryException e) {
context.setVariable("retries", retry);
getDatabase().getLocalCache().clear();
if (retry >= maxRetry)
throw e;
waitForNextRetry();
}
}
return lastResult;
}
use of com.orientechnologies.orient.core.exception.OTransactionException in project orientdb by orientechnologies.
the class OTransactionOptimistic method rollback.
@Override
public void rollback(boolean force, int commitLevelDiff) {
if (txStartCounter < 0)
throw new OStorageException("Invalid value of TX counter");
checkTransaction();
txStartCounter += commitLevelDiff;
status = TXSTATUS.ROLLBACKING;
if (!force && txStartCounter > 0) {
OLogManager.instance().debug(this, "Nested transaction was closed but transaction itself was scheduled for rollback.");
return;
}
if (txStartCounter < 0)
throw new OTransactionException("Transaction was rolled back more times than it was started.");
database.getStorage().callInLock(new Callable<Void>() {
public Void call() throws Exception {
database.getStorage().rollback(OTransactionOptimistic.this);
return null;
}
}, true);
// CLEAR THE CACHE
database.getLocalCache().clear();
// REMOVE ALL THE DIRTY ENTRIES AND UNDO ANY DIRTY DOCUMENT IF POSSIBLE.
for (ORecordOperation v : allEntries.values()) {
final ORecord rec = v.getRecord();
if (rec.isDirty())
if (rec instanceof ODocument && ((ODocument) rec).isTrackingChanges())
((ODocument) rec).undo();
else
rec.unload();
}
close();
status = TXSTATUS.ROLLED_BACK;
}
use of com.orientechnologies.orient.core.exception.OTransactionException 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);
}
}
}
use of com.orientechnologies.orient.core.exception.OTransactionException in project orientdb by orientechnologies.
the class OrientTransactionalGraph method begin.
@Override
public void begin() {
makeActive();
// database transaction to support this behaviour.
if (isAutoStartTx() && getDatabase().getTransaction().isActive())
throw new OTransactionException("A mixture of auto started and manually started transactions is not allowed. " + "Disable auto transactions for the graph before starting a manual transaction.");
getDatabase().begin();
getDatabase().getTransaction().setUsingLog(settings.isUseLog());
}
use of com.orientechnologies.orient.core.exception.OTransactionException in project orientdb by orientechnologies.
the class OObjectSerializerHelper method toStream.
/**
* Serialize the user POJO to a ORecordDocument instance.
*
* @param iPojo
* User pojo to serialize
* @param iRecord
* Record where to update
* @param iObj2RecHandler
*/
public static ODocument toStream(final Object iPojo, final ODocument iRecord, final OEntityManager iEntityManager, final OClass schemaClass, final OUserObject2RecordHandler iObj2RecHandler, final ODatabaseObject db, final boolean iSaveOnlyDirty) {
if (iSaveOnlyDirty && !iRecord.isDirty())
return iRecord;
final long timer = Orient.instance().getProfiler().startChrono();
final Integer identityRecord = System.identityHashCode(iRecord);
if (OSerializationThreadLocal.INSTANCE.get().contains(identityRecord))
return iRecord;
OSerializationThreadLocal.INSTANCE.get().add(identityRecord);
OProperty schemaProperty;
final Class<?> pojoClass = iPojo.getClass();
final List<Field> properties = getClassFields(pojoClass);
// CHECK FOR ID BINDING
final Field idField = fieldIds.get(pojoClass);
if (idField != null) {
Object id = getFieldValue(iPojo, idField.getName());
if (id != null) {
// FOUND
if (id instanceof ORecordId) {
ORecordInternal.setIdentity(iRecord, (ORecordId) id);
} else if (id instanceof Number) {
// TREATS AS CLUSTER POSITION
((ORecordId) iRecord.getIdentity()).setClusterId(schemaClass.getDefaultClusterId());
((ORecordId) iRecord.getIdentity()).setClusterPosition(((Number) id).longValue());
} else if (id instanceof String)
((ORecordId) iRecord.getIdentity()).fromString((String) id);
else if (id.getClass().equals(Object.class))
ORecordInternal.setIdentity(iRecord, (ORecordId) id);
else
OLogManager.instance().warn(OObjectSerializerHelper.class, "@Id field has been declared as %s while the supported are: ORID, Number, String, Object", id.getClass());
}
}
// CHECK FOR VERSION BINDING
final Field vField = fieldVersions.get(pojoClass);
boolean versionConfigured = false;
if (vField != null) {
versionConfigured = true;
Object ver = getFieldValue(iPojo, vField.getName());
final int version = convertVersion(ver);
ORecordInternal.setVersion(iRecord, version);
}
if (db.isMVCC() && !versionConfigured && db.getTransaction() instanceof OTransactionOptimistic)
throw new OTransactionException("Cannot involve an object of class '" + pojoClass + "' in an Optimistic Transaction commit because it does not define @Version or @OVersion and therefore cannot handle MVCC");
// SET OBJECT CLASS
iRecord.setClassName(schemaClass != null ? schemaClass.getName() : null);
String fieldName;
Object fieldValue;
// CALL BEFORE MARSHALLING
invokeCallback(iPojo, iRecord, OBeforeSerialization.class);
for (Field p : properties) {
fieldName = p.getName();
if (idField != null && fieldName.equals(idField.getName()))
continue;
if (vField != null && fieldName.equals(vField.getName()))
continue;
fieldValue = serializeFieldValue(getFieldType(iPojo, fieldName), getFieldValue(iPojo, fieldName));
schemaProperty = schemaClass != null ? schemaClass.getProperty(fieldName) : null;
if (fieldValue != null) {
if (isEmbeddedObject(iPojo.getClass(), fieldValue.getClass(), fieldName, iEntityManager)) {
// AUTO CREATE SCHEMA PROPERTY
if (schemaClass == null) {
db.getMetadata().getSchema().createClass(iPojo.getClass());
iRecord.setClassNameIfExists(iPojo.getClass().getSimpleName());
}
if (schemaProperty == null) {
OType t = OType.getTypeByClass(fieldValue.getClass());
if (t == null)
t = OType.EMBEDDED;
schemaProperty = iRecord.getSchemaClass().createProperty(fieldName, t);
}
}
}
fieldValue = typeToStream(fieldValue, schemaProperty != null ? schemaProperty.getType() : null, iEntityManager, iObj2RecHandler, db, iRecord, iSaveOnlyDirty);
iRecord.field(fieldName, fieldValue);
}
iObj2RecHandler.registerUserObject(iPojo, iRecord);
// CALL AFTER MARSHALLING
invokeCallback(iPojo, iRecord, OAfterSerialization.class);
OSerializationThreadLocal.INSTANCE.get().remove(identityRecord);
Orient.instance().getProfiler().stopChrono("Object.toStream", "Serialize object to stream", timer);
return iRecord;
}
Aggregations