or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddatabase-management.mdevents.mdgraph-database.mdgraph-model.mdindex.mdprocedures.mdquery-execution.mdschema.mdspatial.mdtraversal.md

events.mddocs/

0

# Event Handling

1

2

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

3

4

## Capabilities

5

6

### Transaction Event Listener

7

8

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

9

10

```java { .api }

11

/**

12

* Listen to transaction lifecycle events

13

*/

14

public interface TransactionEventListener<T> {

15

16

/**

17

* Called before a transaction is committed

18

* @param data Transaction data containing changes

19

* @param transaction The transaction being committed

20

* @return State object passed to afterCommit/afterRollback

21

* @throws Exception to prevent commit and trigger rollback

22

*/

23

T beforeCommit(TransactionData data, Transaction transaction) throws Exception;

24

25

/**

26

* Called after a transaction is successfully committed

27

* @param data Transaction data containing changes

28

* @param state State object returned from beforeCommit

29

* @param transaction The committed transaction

30

*/

31

void afterCommit(TransactionData data, T state, Transaction transaction);

32

33

/**

34

* Called after a transaction is rolled back

35

* @param data Transaction data containing changes

36

* @param state State object returned from beforeCommit (may be null)

37

* @param transaction The rolled back transaction

38

*/

39

void afterRollback(TransactionData data, T state, Transaction transaction);

40

}

41

```

42

43

**Usage Examples:**

44

45

```java

46

import org.neo4j.graphdb.event.TransactionEventListener;

47

import org.neo4j.graphdb.event.TransactionData;

48

49

public class AuditTransactionListener implements TransactionEventListener<Long> {

50

51

@Override

52

public Long beforeCommit(TransactionData data, Transaction transaction) throws Exception {

53

long startTime = System.currentTimeMillis();

54

55

// Validate changes before commit

56

for (Node createdNode : data.createdNodes()) {

57

if (createdNode.hasLabel(Label.label("User"))) {

58

if (!createdNode.hasProperty("email")) {

59

throw new IllegalStateException("User nodes must have email property");

60

}

61

}

62

}

63

64

// Log significant changes

65

if (data.createdNodes().iterator().hasNext() ||

66

data.deletedNodes().iterator().hasNext()) {

67

System.out.println("Transaction contains node changes");

68

}

69

70

return startTime;

71

}

72

73

@Override

74

public void afterCommit(TransactionData data, Long startTime, Transaction transaction) {

75

long duration = System.currentTimeMillis() - startTime;

76

77

// Log successful commit

78

System.out.println("Transaction committed in " + duration + "ms");

79

System.out.println(" Nodes created: " + count(data.createdNodes()));

80

System.out.println(" Nodes deleted: " + count(data.deletedNodes()));

81

System.out.println(" Relationships created: " + count(data.createdRelationships()));

82

System.out.println(" Relationships deleted: " + count(data.deletedRelationships()));

83

84

// Trigger external systems

85

notifyExternalSystems(data);

86

}

87

88

@Override

89

public void afterRollback(TransactionData data, Long startTime, Transaction transaction) {

90

if (startTime != null) {

91

long duration = System.currentTimeMillis() - startTime;

92

System.out.println("Transaction rolled back after " + duration + "ms");

93

}

94

}

95

96

private int count(Iterable<?> iterable) {

97

int count = 0;

98

for (Object ignored : iterable) count++;

99

return count;

100

}

101

102

private void notifyExternalSystems(TransactionData data) {

103

// Send notifications to external systems

104

// e.g., message queues, webhooks, etc.

105

}

106

}

107

108

// Register the listener

109

DatabaseManagementService managementService = // ... create service

110

GraphDatabaseService db = managementService.database("neo4j");

111

db.registerTransactionEventListener(new AuditTransactionListener());

112

```

113

114

### Database Event Listener

115

116

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

117

118

```java { .api }

119

/**

120

* Listen to database lifecycle events

121

*/

122

public interface DatabaseEventListener {

123

124

/**

125

* Called when a database is created

126

* @param eventContext Context information about the event

127

*/

128

void databaseCreate(DatabaseEventContext eventContext);

129

130

/**

131

* Called when a database is dropped

132

* @param eventContext Context information about the event

133

*/

134

void databaseDrop(DatabaseEventContext eventContext);

135

136

/**

137

* Called when a database is started

138

* @param eventContext Context information about the event

139

*/

140

void databaseStart(DatabaseEventContext eventContext);

141

142

/**

143

* Called when a database is shut down

144

* @param eventContext Context information about the event

145

*/

146

void databaseShutdown(DatabaseEventContext eventContext);

147

}

148

```

149

150

**Usage Examples:**

151

152

```java

153

import org.neo4j.graphdb.event.DatabaseEventListener;

154

import org.neo4j.graphdb.event.DatabaseEventContext;

155

156

public class DatabaseLifecycleListener implements DatabaseEventListener {

157

158

@Override

159

public void databaseCreate(DatabaseEventContext eventContext) {

160

String dbName = eventContext.getDatabaseName();

161

System.out.println("Database created: " + dbName);

162

163

// Initialize new database with default data

164

initializeDatabase(dbName);

165

166

// Log to audit system

167

auditLog("DATABASE_CREATED", dbName, eventContext.getEventData());

168

}

169

170

@Override

171

public void databaseDrop(DatabaseEventContext eventContext) {

172

String dbName = eventContext.getDatabaseName();

173

System.out.println("Database dropped: " + dbName);

174

175

// Cleanup external resources

176

cleanupExternalResources(dbName);

177

178

// Log to audit system

179

auditLog("DATABASE_DROPPED", dbName, eventContext.getEventData());

180

}

181

182

@Override

183

public void databaseStart(DatabaseEventContext eventContext) {

184

String dbName = eventContext.getDatabaseName();

185

System.out.println("Database started: " + dbName);

186

187

// Perform startup tasks

188

performStartupTasks(dbName);

189

190

// Register for monitoring

191

registerForMonitoring(dbName);

192

}

193

194

@Override

195

public void databaseShutdown(DatabaseEventContext eventContext) {

196

String dbName = eventContext.getDatabaseName();

197

System.out.println("Database shutting down: " + dbName);

198

199

// Perform cleanup tasks

200

performShutdownTasks(dbName);

201

202

// Unregister from monitoring

203

unregisterFromMonitoring(dbName);

204

}

205

206

private void initializeDatabase(String dbName) {

207

// Add default constraints, indexes, or seed data

208

}

209

210

private void cleanupExternalResources(String dbName) {

211

// Clean up external caches, connections, etc.

212

}

213

214

private void auditLog(String event, String dbName, Map<String, Object> data) {

215

// Log to external audit system

216

}

217

}

218

219

// Register the listener

220

DatabaseManagementService managementService = new DatabaseManagementServiceBuilder(dbPath)

221

.addDatabaseListener(new DatabaseLifecycleListener())

222

.build();

223

```

224

225

### Transaction Data Interface

226

227

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

228

229

```java { .api }

230

/**

231

* Access transaction change data

232

*/

233

public interface TransactionData {

234

235

/**

236

* Get nodes created in this transaction

237

* @return Iterable of created nodes

238

*/

239

Iterable<Node> createdNodes();

240

241

/**

242

* Get nodes deleted in this transaction

243

* @return Iterable of deleted nodes

244

*/

245

Iterable<Node> deletedNodes();

246

247

/**

248

* Get relationships created in this transaction

249

* @return Iterable of created relationships

250

*/

251

Iterable<Relationship> createdRelationships();

252

253

/**

254

* Get relationships deleted in this transaction

255

* @return Iterable of deleted relationships

256

*/

257

Iterable<Relationship> deletedRelationships();

258

259

/**

260

* Check if a node was created in this transaction

261

* @param node Node to check

262

* @return true if node was created

263

*/

264

boolean isCreated(Node node);

265

266

/**

267

* Check if a node was deleted in this transaction

268

* @param node Node to check

269

* @return true if node was deleted

270

*/

271

boolean isDeleted(Node node);

272

273

/**

274

* Check if a relationship was created in this transaction

275

* @param relationship Relationship to check

276

* @return true if relationship was created

277

*/

278

boolean isCreated(Relationship relationship);

279

280

/**

281

* Check if a relationship was deleted in this transaction

282

* @param relationship Relationship to check

283

* @return true if relationship was deleted

284

*/

285

boolean isDeleted(Relationship relationship);

286

287

/**

288

* Get assigned properties for a node

289

* @param node Node to get properties for

290

* @return Property container with assigned properties

291

*/

292

PropertyContainer assignedNodeProperties(Node node);

293

294

/**

295

* Get removed properties for a node

296

* @param node Node to get properties for

297

* @return Property container with removed properties

298

*/

299

PropertyContainer removedNodeProperties(Node node);

300

301

/**

302

* Get assigned properties for a relationship

303

* @param relationship Relationship to get properties for

304

* @return Property container with assigned properties

305

*/

306

PropertyContainer assignedRelationshipProperties(Relationship relationship);

307

308

/**

309

* Get removed properties for a relationship

310

* @param relationship Relationship to get properties for

311

* @return Property container with removed properties

312

*/

313

PropertyContainer removedRelationshipProperties(Relationship relationship);

314

315

/**

316

* Get assigned labels for a node

317

* @param node Node to get labels for

318

* @return Iterable of assigned labels

319

*/

320

Iterable<Label> assignedLabels(Node node);

321

322

/**

323

* Get removed labels for a node

324

* @param node Node to get labels for

325

* @return Iterable of removed labels

326

*/

327

Iterable<Label> removedLabels(Node node);

328

}

329

```

330

331

**Advanced Usage Examples:**

332

333

```java

334

public class ChangeTrackingListener implements TransactionEventListener<Map<String, Object>> {

335

336

@Override

337

public Map<String, Object> beforeCommit(TransactionData data, Transaction transaction) {

338

Map<String, Object> changesSummary = new HashMap<>();

339

340

// Track node changes

341

Map<String, Integer> nodeChanges = new HashMap<>();

342

343

// Count created nodes by label

344

for (Node node : data.createdNodes()) {

345

for (Label label : node.getLabels()) {

346

nodeChanges.merge("created_" + label.name(), 1, Integer::sum);

347

}

348

}

349

350

// Count deleted nodes by label

351

for (Node node : data.deletedNodes()) {

352

for (Label label : node.getLabels()) {

353

nodeChanges.merge("deleted_" + label.name(), 1, Integer::sum);

354

}

355

}

356

357

changesSummary.put("nodeChanges", nodeChanges);

358

359

// Track relationship changes

360

Map<String, Integer> relChanges = new HashMap<>();

361

362

for (Relationship rel : data.createdRelationships()) {

363

relChanges.merge("created_" + rel.getType().name(), 1, Integer::sum);

364

}

365

366

for (Relationship rel : data.deletedRelationships()) {

367

relChanges.merge("deleted_" + rel.getType().name(), 1, Integer::sum);

368

}

369

370

changesSummary.put("relationshipChanges", relChanges);

371

372

// Track property changes

373

int propertyChanges = 0;

374

375

// Check nodes for property changes

376

for (Node node : data.createdNodes()) {

377

PropertyContainer assigned = data.assignedNodeProperties(node);

378

for (String key : assigned.getPropertyKeys()) {

379

propertyChanges++;

380

}

381

}

382

383

// Check for property updates on existing nodes

384

// (This requires checking all nodes and comparing with removed properties)

385

386

changesSummary.put("totalPropertyChanges", propertyChanges);

387

388

return changesSummary;

389

}

390

391

@Override

392

public void afterCommit(TransactionData data, Map<String, Object> changesSummary,

393

Transaction transaction) {

394

395

// Log detailed changes

396

System.out.println("Transaction committed with changes:");

397

System.out.println(" Node changes: " + changesSummary.get("nodeChanges"));

398

System.out.println(" Relationship changes: " + changesSummary.get("relationshipChanges"));

399

System.out.println(" Property changes: " + changesSummary.get("totalPropertyChanges"));

400

401

// Send to monitoring system

402

sendToMonitoringSystem(changesSummary);

403

404

// Update search indexes or caches

405

updateExternalSystems(data);

406

}

407

408

@Override

409

public void afterRollback(TransactionData data, Map<String, Object> changesSummary,

410

Transaction transaction) {

411

System.out.println("Transaction rolled back - changes discarded");

412

if (changesSummary != null) {

413

System.out.println(" Would have applied: " + changesSummary);

414

}

415

}

416

417

private void sendToMonitoringSystem(Map<String, Object> changes) {

418

// Send metrics to monitoring system like Prometheus, DataDog, etc.

419

}

420

421

private void updateExternalSystems(TransactionData data) {

422

// Update search indexes, caches, message queues, etc.

423

}

424

}

425

```