Rash
Rash

Reputation: 8242

Trouble understanding Neo4j JDBC Transaction

I am pretty sure that this is a silly question, but I am totally confused here. I am used to code with neo4j-embedded-api and very new to neo4j-jdbc. I want to use Neo4j-JDBC. My Neo4J 2.1.7 instance is hosted on another computer which is accessible via 192.168.1.16:7474

I can create simple programs and write cypher queries and execute them. However, I would like to wrap all of them in a transactional block. Something like this:

    try(Transaction tx = this.graphDatabaseService.beginTx())
    {
        ResultSet resultSet = connect.createStatement().executeQuery(cypherQuery);
        tx.success();
    }

My issue is that I do not know how to get the object of GraphDatabaseService from this:

Neo4jConnection connect = new Driver().connect("jdbc:neo4j://192.168.1.16:7474", new Properties());

Once I have the GraphDatabaseObject, I am assuming that I can use the transactional block like neo4j-embedded-api.

[My Objective] What I am trying to attempt here is to have multiple queries to be sent over the network in a nested-transaction block and if any one of them fails, to rollback all of them.

My failed attempts till now:

I tried to read the neo4j-jdbc project hosted on github and from their test case (link here) I am assuming that to put a code in transaction block you have to connect.setAutoCommit(false); and then use commit() and rollback() functions respectively.

Upvotes: 2

Views: 592

Answers (2)

Rash
Rash

Reputation: 8242

Just to add to Michael Hunger's answer, I made this program which does multiple transactions and rolls back them. This is a very easy program. Hope it helps other noobies like me.

package rash.experiments.neo4j.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.neo4j.jdbc.Driver;
import org.neo4j.jdbc.Neo4jConnection;

public class JdbcTest
{
    public Neo4jConnection connect;

    public JdbcTest() throws SQLException
    {
        this.connect = new Driver().connect("jdbc:neo4j://192.168.1.16:7474", new Properties());
    }

    public static void main(String args[])
    {
        JdbcTest test = null;

        try
        {
            test = new JdbcTest();
            test.connect.setAutoCommit(false);

            long user1 = test.createUser("rash");
            long user2 = test.createUser("honey");
            test.createRelationship(user1, user2);

            test.connect.commit();
        }
        catch(SQLException sqlException)
        {
            try
            {
                test.connect.rollback();
            }
            catch (SQLException e){}
        }
    }

    private long createUser(String userId) throws SQLException
    {
        ResultSet resultSet = this.connect.createStatement().executeQuery("create (user:User {userId: '" + userId + "'}) return id(user) as id");
        resultSet.next();
        return resultSet.getLong("id");
    }

    private void createRelationship(long node1, long node2) throws SQLException
    {
        this.connect.createStatement().executeQuery("start user1 = node(" + node1 + "), user2 = node(" + node2 + ") create (user1) -[:KNOWS]-> (user2)");
        throw new SQLException();
    }
}

This program will never commit because method createRelationship() throws an error and the program never gets a chance to commit. Instead it rolls back.

Upvotes: 0

Michael Hunger
Michael Hunger

Reputation: 41706

If you don't know JDBC then please read up on it, it's a remote API which works by executing statement (Cypher in this case) against a remote API.

There is no GraphDatabaseService object. Only statements and parameters.

For tx handling you either have one tx per statement or if you set connection.setAutoCommit(false); then the transaction runs until you call connection.commit()

Upvotes: 2

Related Questions