-
Notifications
You must be signed in to change notification settings - Fork 872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
execute() in transactions doesn't UPDATE records #8632
Comments
@luigidellaquila I did check this one, and it looks like it was not fixed by closing #8634, as you suspected. |
Thank you very much @mmacfadden , I'll check this asap Thanks Luigi |
@luigidellaquila Greetings! I have updated the test case, so that it is easily re-runable. I have also converted the schema and data creation to use the API instead of using scripts, just to rule out errors in the schema or data. I just tested this with the 3.0.12 and verified the issue remains. Here is the updated test case: import java.util.HashMap;
import java.util.Map;
import com.orientechnologies.orient.core.db.ODatabaseSession;
import com.orientechnologies.orient.core.db.ODatabaseType;
import com.orientechnologies.orient.core.db.OrientDB;
import com.orientechnologies.orient.core.db.OrientDBConfig;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.metadata.schema.OSchema;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.record.OElement;
public class OdbScriptTest2 {
public static final String SQL = "sql";
public static final String DB_NAME = "test";
public static final String CHILD = "Child";
public static final String PARENT = "Parent";
public static void main(String[] args) {
final OrientDB odb = new OrientDB("remote:localhost", "root", "root", OrientDBConfig.defaultConfig());
if (!odb.exists(DB_NAME)) {
odb.create(DB_NAME, ODatabaseType.PLOCAL);
}
final ODatabaseSession db = odb.open(DB_NAME, "admin", "admin");
final OSchema schema = db.getMetadata().getSchema();
if (schema.existsClass(CHILD)) {
schema.dropClass(CHILD);
}
final OClass childClass = schema.createClass("Child");
childClass.createProperty("id", OType.STRING);
if (schema.existsClass(PARENT)) {
schema.dropClass(PARENT);
}
final OClass parentClass = schema.createClass("Parent");
parentClass.createProperty("id", OType.STRING);
parentClass.createProperty("children", OType.LINKMAP, childClass);
//
// Create the Data
//
// Child
final OElement childDoc = db.newElement("Child");
childDoc.setProperty("id", "child");
childDoc.save();
// Parent
final OElement parentDoc = db.newElement("Parent");
parentDoc.setProperty("id", "parent");
final Map<String, OElement> children = new HashMap<>();
children.put("child", childDoc);
parentDoc.setProperty("children", children);
parentDoc.save();
// Check The Current Database State
System.out.println("Child exists: " + db.command("SELECT FROM Child", new HashMap<>()).next());
System.out.println("Parent has Child: " + db.command("SELECT FROM Parent", new HashMap<>()).next());
// This script should delete the child, and remove the child from the parent's map.
final String delete = "LET parents = SELECT FROM Parent WHERE id = \"parent\";\n"
+ "LET p = $parents[0];\n"
+ "LET directChildrenToDelete = SELECT expand($p.children.`child`);\n"
+ "LET allChildrenToDelete = TRAVERSE children FROM (SELECT expand($directChildrenToDelete));\n"
+ "DELETE FROM (SELECT expand($allChildrenToDelete));\n"
+ "UPDATE (SELECT expand($p)) REMOVE children.`child`;";
// Update inside a transaction
db.begin();
db.execute(SQL, delete, new HashMap<>());
db.commit();
// Check the updated state
final Long childCount = db
.command("SELECT count(*) as count FROM Child", new HashMap<>())
.next()
.toElement()
.getProperty("count");
System.out.println("Child deleted. Number of Child documents: " + childCount);
final OElement updatedParent = db
.command("SELECT FROM Parent", new HashMap<String, Object>())
.next()
.toElement();
System.out.println("Parent not updated: " + updatedParent);
final Map<String, OElement> updatedChildren = updatedParent.getProperty("children");
System.out.println("Updated children: " + updatedChildren);
final OElement updatedChild = updatedChildren.get(CHILD);
System.out.println("Child does not exist: " + updatedChild);
db.close();
odb.close();
}
} |
As a side note, I tried pulling the 3.0.12 tag, and importing into eclipse so that I could help debug, but I seem to be unable to get the code to compile in eclipse or in maven. If I can get it working I am happy to help debug. Is there a stable tag, or a trick to getting it building? |
@luigidellaquila Finally got to do some debugging. I noticed that if you look at the script execution context here: orientdb/core/src/main/java/com/orientechnologies/orient/core/command/OSqlScriptExecutor.java Line 76 in ac16faa
We can see that the Parent element has actually had its child removed from the LINKMAP. So it looks like the execute worked, as far as the script execution. When committing, in OAbstractPaginatedStorage#commit: Line 2028 in ac16faa
We see the following for
The A few lines later (2148) we call OAbstractPaginatedStorage.commitEntry. On line 5008 we call Line 4422 in ac16faa
Therefore it seems like we never write the updated Parent record to storage. The questions is why is the _contentChanged flag in the record set to false? |
I also noticed that when the |
OrientDB Version: 3.0.12
Java Version: Java 8
OS: Linux
Expected behavior
A script run in a transaction should atomically commit or fail.
Actual behavior
The script only partially executes and appears to fail silently.
Steps to reproduce
Execute this Java class with a server running locally.
This will print:
The
DELETE FROM (SELECT expand($allChildrenToDelete));
successfully deleted the child record. But theUPDATE (SELECT expand($p)) REMOVE children.
child;
did not work. Things to note:db.begin()
anddb.comit()
from around the final execute the code works.UPDATE Parent REMOVE children.child WHERE id = "parent";
It still does not work.BEGIN;
andCOMMIT;
within the script causes an exception.The text was updated successfully, but these errors were encountered: