Transactions in custom procedures not rolling back on failure


Apologies if the question is trivial but I'm new with the platform.
I'm writing custom Java procedures for Neo4j and I noticed that transactions marked as failure are not being rolled back. Here's a sample code:

public GraphDatabaseService db;

@Procedure(value = "xxx.yyy.create", mode = Mode.WRITE)
@Description("Create new node")
public Stream<NodeResult> create(@Name("map") final Map<String, Object> map,
        @Name("direction") final String direction,
        @Name("relationshipType") final String relationshipType)
            throws GraphServicesException {
    final String string = JsonUtils.serialize(map);
    final MyClass myClass = JsonUtils.deserializeObj(string, MyClass.class);
    if (null == myClass) {
        return Stream.empty();
    try (Transaction tx = db.beginTx()) {
        try {
            final Node node = GraphUgcService.create(db, myClass, direction, relationshipType);
            if (null != node) {
                return Stream.of(new NodeResult(node));
        } catch (final GraphServicesException e) {
            logger.error("Insert failed for: " + string, e);
            throw e;
        } finally {
    return Stream.empty();

The transaction above is never rolled back even though tx.failure() is executed.

I've noticed that tx at runtime is of class PlaceboTransaction, if that helps. Finally, if I access tx.currentTransaction at runtime and call failure() on it, it does roll back. Any idea of what's wrong?

Thanks in advance.

In most cases you don't have to do transaction management in a procedure yourself. You're inheriting a transactional context from the statement containing the proceudre call.
Any exception being thrown by your procedure will rollback the transaction.

If you want to manage transactions explicitly you have to create a new thread and do gds.beginTx() there.

Alternatively you can also add @Context public ProcedureTransaction procedureTransaction; and run its terminate() or failure() method.

Hi Stefan, thank you for your answer.

I'm not sure what my problem is, but no solution is working for me. I create nodes in a procedures and then, on failure, the nodes creation is not rolled back. I tried running it into a separate thread, explicitly using transactions, and with the @Context ProcedureTransaction, using the explicit failure() call.

If I try to terminate(), any other operation on the graph throws the following exception:

The transaction has been terminated.
Retry your operation in a new transaction, and you should see a successful result.
Explicitly terminated by the user. 

Can you tell us what this is? And if this is your custom code can you add that code here?

If this ends up doing a new transaction in a separate thread that might explain your observations.