Sometimes you may want to terminate (abort) a long running transaction from another thread.
Tip The source code used in this example is found here: TerminateTransactions.java |
To begin with, we start the database server:
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase( DB_PATH );
Now we start creating an infinite binary tree of nodes in the database, as an example of a long running transaction.
RelationshipType relType = RelationshipType.withName( "CHILD" ); Queue<Node> nodes = new LinkedList<>(); int depth = 1; try ( Transaction tx = graphDb.beginTx() ) { Node rootNode = graphDb.createNode(); nodes.add( rootNode ); for (; true; depth++) { int nodesToExpand = nodes.size(); for (int i = 0; i < nodesToExpand; ++i) { Node parent = nodes.remove(); Node left = graphDb.createNode(); Node right = graphDb.createNode(); parent.createRelationshipTo( left, relType ); parent.createRelationshipTo( right, relType ); nodes.add( left ); nodes.add( right ); } } } catch ( TransactionTerminatedException ignored ) { return String.format( "Created tree up to depth %s in 1 sec", depth ); }
After waiting for some time, we decide to terminate the transaction. This is done from a separate thread.
tx.terminate();
Running this will execute the long running transaction for about one second and prints the maximum depth of the tree that was created before the transaction was terminated. No changes are actually made to the data — because the transaction has been terminated, the end result is as if no operations were performed.
Example output
Created tree up to depth 16 in 1 sec
Finally, let’s shut down the database again.
graphDb.shutdown();