CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-neo4j--neo4j

Neo4j Community Edition - The world's leading Graph Database with Cypher query language and ACID transactions.

Pending
Overview
Eval results
Files

events.mddocs/

Event Handling

Comprehensive event system for monitoring database lifecycle, transaction events, and data changes with support for custom event listeners and transaction data inspection.

Capabilities

Transaction Event Listener

Interface for listening to transaction lifecycle events with before/after commit and rollback hooks.

/**
 * Listen to transaction lifecycle events
 */
public interface TransactionEventListener<T> {
    
    /**
     * Called before a transaction is committed
     * @param data Transaction data containing changes
     * @param transaction The transaction being committed
     * @return State object passed to afterCommit/afterRollback
     * @throws Exception to prevent commit and trigger rollback
     */
    T beforeCommit(TransactionData data, Transaction transaction) throws Exception;
    
    /**
     * Called after a transaction is successfully committed
     * @param data Transaction data containing changes
     * @param state State object returned from beforeCommit
     * @param transaction The committed transaction
     */
    void afterCommit(TransactionData data, T state, Transaction transaction);
    
    /**
     * Called after a transaction is rolled back
     * @param data Transaction data containing changes
     * @param state State object returned from beforeCommit (may be null)
     * @param transaction The rolled back transaction
     */
    void afterRollback(TransactionData data, T state, Transaction transaction);
}

Usage Examples:

import org.neo4j.graphdb.event.TransactionEventListener;
import org.neo4j.graphdb.event.TransactionData;

public class AuditTransactionListener implements TransactionEventListener<Long> {
    
    @Override
    public Long beforeCommit(TransactionData data, Transaction transaction) throws Exception {
        long startTime = System.currentTimeMillis();
        
        // Validate changes before commit
        for (Node createdNode : data.createdNodes()) {
            if (createdNode.hasLabel(Label.label("User"))) {
                if (!createdNode.hasProperty("email")) {
                    throw new IllegalStateException("User nodes must have email property");
                }
            }
        }
        
        // Log significant changes
        if (data.createdNodes().iterator().hasNext() || 
            data.deletedNodes().iterator().hasNext()) {
            System.out.println("Transaction contains node changes");
        }
        
        return startTime;
    }
    
    @Override
    public void afterCommit(TransactionData data, Long startTime, Transaction transaction) {
        long duration = System.currentTimeMillis() - startTime;
        
        // Log successful commit
        System.out.println("Transaction committed in " + duration + "ms");
        System.out.println("  Nodes created: " + count(data.createdNodes()));
        System.out.println("  Nodes deleted: " + count(data.deletedNodes()));
        System.out.println("  Relationships created: " + count(data.createdRelationships()));
        System.out.println("  Relationships deleted: " + count(data.deletedRelationships()));
        
        // Trigger external systems
        notifyExternalSystems(data);
    }
    
    @Override
    public void afterRollback(TransactionData data, Long startTime, Transaction transaction) {
        if (startTime != null) {
            long duration = System.currentTimeMillis() - startTime;
            System.out.println("Transaction rolled back after " + duration + "ms");
        }
    }
    
    private int count(Iterable<?> iterable) {
        int count = 0;
        for (Object ignored : iterable) count++;
        return count;
    }
    
    private void notifyExternalSystems(TransactionData data) {
        // Send notifications to external systems
        // e.g., message queues, webhooks, etc.
    }
}

// Register the listener
DatabaseManagementService managementService = // ... create service
GraphDatabaseService db = managementService.database("neo4j");
db.registerTransactionEventListener(new AuditTransactionListener());

Database Event Listener

Interface for listening to database lifecycle events including creation, deletion, startup, and shutdown.

/**
 * Listen to database lifecycle events
 */
public interface DatabaseEventListener {
    
    /**
     * Called when a database is created
     * @param eventContext Context information about the event
     */
    void databaseCreate(DatabaseEventContext eventContext);
    
    /**
     * Called when a database is dropped
     * @param eventContext Context information about the event
     */
    void databaseDrop(DatabaseEventContext eventContext);
    
    /**
     * Called when a database is started
     * @param eventContext Context information about the event
     */
    void databaseStart(DatabaseEventContext eventContext);
    
    /**
     * Called when a database is shut down
     * @param eventContext Context information about the event
     */
    void databaseShutdown(DatabaseEventContext eventContext);
}

Usage Examples:

import org.neo4j.graphdb.event.DatabaseEventListener;
import org.neo4j.graphdb.event.DatabaseEventContext;

public class DatabaseLifecycleListener implements DatabaseEventListener {
    
    @Override
    public void databaseCreate(DatabaseEventContext eventContext) {
        String dbName = eventContext.getDatabaseName();
        System.out.println("Database created: " + dbName);
        
        // Initialize new database with default data
        initializeDatabase(dbName);
        
        // Log to audit system
        auditLog("DATABASE_CREATED", dbName, eventContext.getEventData());
    }
    
    @Override
    public void databaseDrop(DatabaseEventContext eventContext) {
        String dbName = eventContext.getDatabaseName();
        System.out.println("Database dropped: " + dbName);
        
        // Cleanup external resources
        cleanupExternalResources(dbName);
        
        // Log to audit system
        auditLog("DATABASE_DROPPED", dbName, eventContext.getEventData());
    }
    
    @Override
    public void databaseStart(DatabaseEventContext eventContext) {
        String dbName = eventContext.getDatabaseName();
        System.out.println("Database started: " + dbName);
        
        // Perform startup tasks
        performStartupTasks(dbName);
        
        // Register for monitoring
        registerForMonitoring(dbName);
    }
    
    @Override
    public void databaseShutdown(DatabaseEventContext eventContext) {
        String dbName = eventContext.getDatabaseName();
        System.out.println("Database shutting down: " + dbName);
        
        // Perform cleanup tasks
        performShutdownTasks(dbName);
        
        // Unregister from monitoring
        unregisterFromMonitoring(dbName);
    }
    
    private void initializeDatabase(String dbName) {
        // Add default constraints, indexes, or seed data
    }
    
    private void cleanupExternalResources(String dbName) {
        // Clean up external caches, connections, etc.
    }
    
    private void auditLog(String event, String dbName, Map<String, Object> data) {
        // Log to external audit system
    }
}

// Register the listener
DatabaseManagementService managementService = new DatabaseManagementServiceBuilder(dbPath)
    .addDatabaseListener(new DatabaseLifecycleListener())
    .build();

Transaction Data Interface

Interface providing access to transaction change data including created, deleted, and modified entities.

/**
 * Access transaction change data
 */
public interface TransactionData {
    
    /**
     * Get nodes created in this transaction
     * @return Iterable of created nodes
     */
    Iterable<Node> createdNodes();
    
    /**
     * Get nodes deleted in this transaction
     * @return Iterable of deleted nodes
     */
    Iterable<Node> deletedNodes();
    
    /**
     * Get relationships created in this transaction
     * @return Iterable of created relationships
     */
    Iterable<Relationship> createdRelationships();
    
    /**
     * Get relationships deleted in this transaction
     * @return Iterable of deleted relationships
     */
    Iterable<Relationship> deletedRelationships();
    
    /**
     * Check if a node was created in this transaction
     * @param node Node to check
     * @return true if node was created
     */
    boolean isCreated(Node node);
    
    /**
     * Check if a node was deleted in this transaction
     * @param node Node to check
     * @return true if node was deleted
     */
    boolean isDeleted(Node node);
    
    /**
     * Check if a relationship was created in this transaction
     * @param relationship Relationship to check
     * @return true if relationship was created
     */
    boolean isCreated(Relationship relationship);
    
    /**
     * Check if a relationship was deleted in this transaction
     * @param relationship Relationship to check
     * @return true if relationship was deleted
     */
    boolean isDeleted(Relationship relationship);
    
    /**
     * Get assigned properties for a node
     * @param node Node to get properties for
     * @return Property container with assigned properties
     */
    PropertyContainer assignedNodeProperties(Node node);
    
    /**
     * Get removed properties for a node
     * @param node Node to get properties for
     * @return Property container with removed properties
     */
    PropertyContainer removedNodeProperties(Node node);
    
    /**
     * Get assigned properties for a relationship
     * @param relationship Relationship to get properties for
     * @return Property container with assigned properties
     */
    PropertyContainer assignedRelationshipProperties(Relationship relationship);
    
    /**
     * Get removed properties for a relationship
     * @param relationship Relationship to get properties for
     * @return Property container with removed properties
     */
    PropertyContainer removedRelationshipProperties(Relationship relationship);
    
    /**
     * Get assigned labels for a node
     * @param node Node to get labels for
     * @return Iterable of assigned labels
     */
    Iterable<Label> assignedLabels(Node node);
    
    /**
     * Get removed labels for a node
     * @param node Node to get labels for
     * @return Iterable of removed labels
     */
    Iterable<Label> removedLabels(Node node);
}

Advanced Usage Examples:

public class ChangeTrackingListener implements TransactionEventListener<Map<String, Object>> {
    
    @Override
    public Map<String, Object> beforeCommit(TransactionData data, Transaction transaction) {
        Map<String, Object> changesSummary = new HashMap<>();
        
        // Track node changes
        Map<String, Integer> nodeChanges = new HashMap<>();
        
        // Count created nodes by label
        for (Node node : data.createdNodes()) {
            for (Label label : node.getLabels()) {
                nodeChanges.merge("created_" + label.name(), 1, Integer::sum);
            }
        }
        
        // Count deleted nodes by label
        for (Node node : data.deletedNodes()) {
            for (Label label : node.getLabels()) {
                nodeChanges.merge("deleted_" + label.name(), 1, Integer::sum);
            }
        }
        
        changesSummary.put("nodeChanges", nodeChanges);
        
        // Track relationship changes
        Map<String, Integer> relChanges = new HashMap<>();
        
        for (Relationship rel : data.createdRelationships()) {
            relChanges.merge("created_" + rel.getType().name(), 1, Integer::sum);
        }
        
        for (Relationship rel : data.deletedRelationships()) {
            relChanges.merge("deleted_" + rel.getType().name(), 1, Integer::sum);
        }
        
        changesSummary.put("relationshipChanges", relChanges);
        
        // Track property changes
        int propertyChanges = 0;
        
        // Check nodes for property changes
        for (Node node : data.createdNodes()) {
            PropertyContainer assigned = data.assignedNodeProperties(node);
            for (String key : assigned.getPropertyKeys()) {
                propertyChanges++;
            }
        }
        
        // Check for property updates on existing nodes
        // (This requires checking all nodes and comparing with removed properties)
        
        changesSummary.put("totalPropertyChanges", propertyChanges);
        
        return changesSummary;
    }
    
    @Override
    public void afterCommit(TransactionData data, Map<String, Object> changesSummary, 
                           Transaction transaction) {
        
        // Log detailed changes
        System.out.println("Transaction committed with changes:");
        System.out.println("  Node changes: " + changesSummary.get("nodeChanges"));
        System.out.println("  Relationship changes: " + changesSummary.get("relationshipChanges"));
        System.out.println("  Property changes: " + changesSummary.get("totalPropertyChanges"));
        
        // Send to monitoring system
        sendToMonitoringSystem(changesSummary);
        
        // Update search indexes or caches
        updateExternalSystems(data);
    }
    
    @Override
    public void afterRollback(TransactionData data, Map<String, Object> changesSummary, 
                             Transaction transaction) {
        System.out.println("Transaction rolled back - changes discarded");
        if (changesSummary != null) {
            System.out.println("  Would have applied: " + changesSummary);
        }
    }
    
    private void sendToMonitoringSystem(Map<String, Object> changes) {
        // Send metrics to monitoring system like Prometheus, DataDog, etc.
    }
    
    private void updateExternalSystems(TransactionData data) {
        // Update search indexes, caches, message queues, etc.
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-neo4j--neo4j

docs

configuration.md

database-management.md

events.md

graph-database.md

graph-model.md

index.md

procedures.md

query-execution.md

schema.md

spatial.md

traversal.md

tile.json