1

Is it possible to determine if a Node is in a transaction? It is possible to get a GraphDatabaseService by the method Node.getGraphDatabase.

I would like to do something like this:

public class Neo4JHelper {
    public void setProperty(Node node, String key, Object value) {
        if(isInTransaction(node) {
            node.setProperty(key, value);
        } else {
            throw new MyOwnException("You are trying to set a node outside a transaction... you suck");
        }
    }

    private boolean isInTransaction(Node node) {
        //Something
    }
}

The reason I want to do this is because I would like to give my users a custom error when trying to use my class Neo4JHelperoutside a transaction.

Another solution would be if it is possible to somehow tell the compiler that you need a transaction to use the method/class and otherwise give a compile error.

David Berg
  • 1,958
  • 1
  • 21
  • 37

2 Answers2

3

I have several different takes on this, I'm not sure which one is most helpful.

Point #1 is that you don't need to do this checking. If you attempt to create any dummy node, and you're not inside of a transaction, the DB will throw an exception indicating that you're not in a transaction. So if you wanted to detect this situation, just try to create a trivial test node. No exception? You're in a transaction.

Point #2 is maybe you're asking if a particular node is in a transaction. I'm not aware of any way to do that, maybe a developer can add something on that. Within transactions, it's possible to acquire a read/write lock on an individual node. So if you had the Transaction object (which your method doesn't) then a surrogate method might be to determine whether there's a lock on a given node.

Point #3 while I'm not 100% sure what you're doing, your code suggest there's a different way of going about this problem so you don't even have to answer this question. If you want your users to get a custom error, go ahead and try to modify the property -- if neo4j throws an exception that you're not in a transaction, again, there's your answer. Catch that exception, then throw your custom error.

FrobberOfBits
  • 17,634
  • 4
  • 52
  • 86
  • I thought about the _Point #3_ alternative, but then I would still prefer if I could check if I was in a transaction before trying to do something. As an example if I think a variable could be `null`at some point in my code, I do not put a try-catch around it and catch a `NullPointerException`, I check if it is null before I try to use it. But if its the only way I guess that is how I will do it. I don´t see the difference between _Point #1_ and _Point #3_, I still need to catch the exception on the first node? The _Point #2_ is not my usecase. Thank you for your answer! – David Berg Nov 06 '15 at 13:37
  • Point #3 is similar to #1, the key advice being, if you approach the problem differently then the question can actually become moot. – FrobberOfBits Nov 06 '15 at 14:48
  • If I would like to build a bridge, a boat is not the answer. Thank you anyway. :) – David Berg Nov 06 '15 at 14:53
2

A node cannot be in a transaction, only a current execution (Thread) can be.

There is an internal way to check for a running transaction:

   ThreadToStatementContextBridge txManager = ((GraphDatabaseAPI) graphDB).getDependencyResolver().resolveDependency(ThreadToStatementContextBridge.class);
   txManager.hasTransaction();
Michael Hunger
  • 41,339
  • 3
  • 57
  • 80