0
# Transaction Support
1
2
Multi-operation transaction capabilities enabling atomic operations across multiple ZooKeeper nodes with support for create, delete, setData, and check operations within a single transaction context.
3
4
## Capabilities
5
6
### CuratorMultiTransaction
7
8
Main interface for creating and executing multi-operation transactions, providing atomic execution of multiple ZooKeeper operations.
9
10
```java { .api }
11
/**
12
* Start a transaction builder
13
* @return builder object
14
*/
15
CuratorMultiTransaction transaction();
16
17
/**
18
* Main interface for multi-operation transactions
19
*/
20
public interface CuratorMultiTransaction extends
21
Backgroundable<ErrorListenerMultiTransactionMain>,
22
CuratorMultiTransactionMain {
23
24
/**
25
* Execute transaction with provided operations
26
* @param operations operations to execute atomically
27
* @return builder for execution
28
*/
29
CuratorMultiTransactionMain forOperations(CuratorOp... operations);
30
31
/**
32
* Execute transaction with provided operations
33
* @param operations operations to execute atomically
34
* @return builder for execution
35
*/
36
CuratorMultiTransactionMain forOperations(Iterable<CuratorOp> operations);
37
}
38
39
public interface CuratorMultiTransactionMain extends
40
Backgroundable<Collection<CuratorTransactionResult>>,
41
ErrorListenerMultiTransactionMain {
42
43
/**
44
* Commit/execute the transaction
45
* @return results of all operations
46
* @throws Exception if transaction fails
47
*/
48
Collection<CuratorTransactionResult> commit() throws Exception;
49
}
50
```
51
52
**Usage Examples:**
53
54
```java
55
import org.apache.curator.framework.api.transaction.CuratorOp;
56
import org.apache.curator.framework.api.transaction.CuratorTransactionResult;
57
58
// Create multiple operations
59
CuratorOp createOp = client.transactionOp()
60
.create()
61
.forPath("/txn/node1", "data1".getBytes());
62
63
CuratorOp setDataOp = client.transactionOp()
64
.setData()
65
.forPath("/existing/node", "new data".getBytes());
66
67
CuratorOp deleteOp = client.transactionOp()
68
.delete()
69
.forPath("/old/node");
70
71
// Execute transaction atomically
72
Collection<CuratorTransactionResult> results = client.transaction()
73
.forOperations(createOp, setDataOp, deleteOp)
74
.commit();
75
76
// Process results
77
for (CuratorTransactionResult result : results) {
78
System.out.println("Operation: " + result.getType() +
79
" Path: " + result.getForPath() +
80
" Result: " + result.getResultPath());
81
}
82
83
// Background transaction
84
client.transaction()
85
.forOperations(createOp, setDataOp)
86
.inBackground((curatorFramework, curatorEvent) -> {
87
Collection<CuratorTransactionResult> results = curatorEvent.getOpResults();
88
System.out.println("Transaction completed with " + results.size() + " operations");
89
})
90
.commit();
91
```
92
93
### TransactionOp Factory
94
95
Factory interface for creating reusable transaction operations that can be combined into atomic transactions.
96
97
```java { .api }
98
/**
99
* Allocate an operation that can be used with transaction()
100
* @return operation builder
101
*/
102
TransactionOp transactionOp();
103
104
/**
105
* Factory for creating reusable transaction operations
106
*/
107
public interface TransactionOp {
108
/**
109
* Create a create operation
110
* @return create operation builder
111
*/
112
TransactionCreateBuilder<CuratorOp> create();
113
114
/**
115
* Create a delete operation
116
* @return delete operation builder
117
*/
118
TransactionDeleteBuilder<CuratorOp> delete();
119
120
/**
121
* Create a setData operation
122
* @return setData operation builder
123
*/
124
TransactionSetDataBuilder<CuratorOp> setData();
125
126
/**
127
* Create a check operation
128
* @return check operation builder
129
*/
130
TransactionCheckBuilder<CuratorOp> check();
131
}
132
```
133
134
### Transaction Create Operations
135
136
Builder for create operations within transactions, supporting all create modes and options.
137
138
```java { .api }
139
public interface TransactionCreateBuilder<T> extends TransactionCreateBuilder2<T> {
140
/**
141
* Create with specific mode
142
* @param mode create mode
143
* @return builder
144
*/
145
PathAndBytesable<T> withMode(CreateMode mode);
146
147
/**
148
* Create with ACL
149
* @param aclList ACL list
150
* @return builder
151
*/
152
ACLCreateModePathAndBytesable<T> withACL(List<ACL> aclList);
153
154
/**
155
* Create with TTL (for TTL nodes)
156
* @param ttl TTL in milliseconds
157
* @return builder
158
*/
159
ACLCreateModePathAndBytesable<T> withTtl(long ttl);
160
}
161
162
public interface TransactionCreateBuilder2<T> extends
163
ACLCreateModePathAndBytesable<T>,
164
CreateModable<ACLPathAndBytesable<T>>,
165
ACLable<CreateModePathAndBytesable<T>>,
166
PathAndBytesable<T> {
167
168
/**
169
* Create parent nodes if needed
170
* @return builder
171
*/
172
ACLCreateModePathAndBytesable<T> creatingParentsIfNeeded();
173
}
174
```
175
176
**Usage Examples:**
177
178
```java
179
// Create operation in transaction
180
CuratorOp createOp = client.transactionOp()
181
.create()
182
.withMode(CreateMode.PERSISTENT)
183
.forPath("/txn/new-node", "initial data".getBytes());
184
185
// Create with ACL
186
List<ACL> acls = Arrays.asList(new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS));
187
CuratorOp createWithAcl = client.transactionOp()
188
.create()
189
.withACL(acls)
190
.withMode(CreateMode.PERSISTENT)
191
.forPath("/secure/node", "secure data".getBytes());
192
193
// Create ephemeral sequential
194
CuratorOp createSequential = client.transactionOp()
195
.create()
196
.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
197
.forPath("/sequence/node-", "sequence data".getBytes());
198
199
// Create with parent creation
200
CuratorOp createWithParents = client.transactionOp()
201
.create()
202
.creatingParentsIfNeeded()
203
.forPath("/deep/nested/path", "nested data".getBytes());
204
```
205
206
### Transaction Delete Operations
207
208
Builder for delete operations within transactions, supporting version checking and recursive deletion.
209
210
```java { .api }
211
public interface TransactionDeleteBuilder<T> extends
212
Pathable<T>,
213
Versionable<Pathable<T>> {
214
215
/**
216
* Delete with version check
217
* @param version version to match
218
* @return builder
219
*/
220
Pathable<T> withVersion(int version);
221
222
/**
223
* Delete children if needed (recursive delete)
224
* @return builder
225
*/
226
Pathable<T> deletingChildrenIfNeeded();
227
}
228
```
229
230
**Usage Examples:**
231
232
```java
233
// Simple delete operation
234
CuratorOp deleteOp = client.transactionOp()
235
.delete()
236
.forPath("/to/delete");
237
238
// Delete with version check
239
CuratorOp deleteVersioned = client.transactionOp()
240
.delete()
241
.withVersion(3)
242
.forPath("/versioned/node");
243
244
// Recursive delete
245
CuratorOp deleteRecursive = client.transactionOp()
246
.delete()
247
.deletingChildrenIfNeeded()
248
.forPath("/parent/with/children");
249
```
250
251
### Transaction SetData Operations
252
253
Builder for setData operations within transactions, supporting version checking and data modification.
254
255
```java { .api }
256
public interface TransactionSetDataBuilder<T> extends
257
Pathable<T>,
258
Versionable<PathAndBytesable<T>> {
259
260
/**
261
* Set data with version check
262
* @param version version to match
263
* @return builder
264
*/
265
PathAndBytesable<T> withVersion(int version);
266
267
/**
268
* Set data with compression
269
* @return builder
270
*/
271
Versionable<PathAndBytesable<T>> compressed();
272
}
273
```
274
275
**Usage Examples:**
276
277
```java
278
// Simple setData operation
279
CuratorOp setDataOp = client.transactionOp()
280
.setData()
281
.forPath("/existing/node", "new data".getBytes());
282
283
// SetData with version check
284
CuratorOp setDataVersioned = client.transactionOp()
285
.setData()
286
.withVersion(2)
287
.forPath("/versioned/node", "updated data".getBytes());
288
289
// SetData with compression
290
CuratorOp setDataCompressed = client.transactionOp()
291
.setData()
292
.compressed()
293
.forPath("/large/node", largeDataBytes);
294
```
295
296
### Transaction Check Operations
297
298
Builder for check operations within transactions, enabling conditional transaction execution based on node version or existence.
299
300
```java { .api }
301
public interface TransactionCheckBuilder<T> extends
302
Pathable<T>,
303
Versionable<Pathable<T>> {
304
305
/**
306
* Check that node has specific version
307
* @param version expected version
308
* @return builder
309
*/
310
Pathable<T> withVersion(int version);
311
}
312
```
313
314
**Usage Examples:**
315
316
```java
317
// Check node version
318
CuratorOp checkOp = client.transactionOp()
319
.check()
320
.withVersion(5)
321
.forPath("/important/node");
322
323
// Use check to ensure preconditions
324
CuratorOp checkExists = client.transactionOp()
325
.check()
326
.forPath("/must/exist");
327
328
// Conditional transaction based on checks
329
Collection<CuratorTransactionResult> results = client.transaction()
330
.forOperations(
331
checkExists, // Ensure node exists
332
client.transactionOp().setData().forPath("/must/exist", "new data".getBytes()),
333
client.transactionOp().create().forPath("/related/node", "related data".getBytes())
334
)
335
.commit();
336
```
337
338
### CuratorOp Interface
339
340
Represents a single operation within a transaction, providing access to operation details.
341
342
```java { .api }
343
/**
344
* Represents a single transaction operation
345
*/
346
public interface CuratorOp {
347
/**
348
* Get the operation type
349
* @return operation type
350
*/
351
OperationType getType();
352
353
/**
354
* Get the path for this operation
355
* @return path
356
*/
357
String getPath();
358
359
/**
360
* Get the data for this operation (if applicable)
361
* @return data bytes or null
362
*/
363
byte[] getData();
364
}
365
```
366
367
### Transaction Results
368
369
Classes for handling transaction execution results and accessing operation outcomes.
370
371
```java { .api }
372
/**
373
* Result of a transaction operation
374
*/
375
public class CuratorTransactionResult {
376
/**
377
* Get the operation type that was executed
378
* @return operation type
379
*/
380
public OperationType getType();
381
382
/**
383
* Get the path that was operated on
384
* @return original path
385
*/
386
public String getForPath();
387
388
/**
389
* Get the actual result path (important for sequential nodes)
390
* @return result path
391
*/
392
public String getResultPath();
393
394
/**
395
* Get the stat information for the operation result
396
* @return stat or null
397
*/
398
public Stat getResultStat();
399
400
/**
401
* Get the error code for this operation (0 = success)
402
* @return ZooKeeper error code
403
*/
404
public int getError();
405
}
406
407
/**
408
* Types of transaction operations
409
*/
410
public enum OperationType {
411
CREATE, DELETE, SET_DATA, CHECK
412
}
413
414
/**
415
* Utility class combining operation type and path
416
*/
417
public class TypeAndPath {
418
/**
419
* Get the operation type
420
* @return operation type
421
*/
422
public OperationType getType();
423
424
/**
425
* Get the path
426
* @return path
427
*/
428
public String getPath();
429
}
430
```
431
432
**Usage Examples:**
433
434
```java
435
// Process transaction results
436
Collection<CuratorTransactionResult> results = client.transaction()
437
.forOperations(createOp, setDataOp, deleteOp)
438
.commit();
439
440
for (CuratorTransactionResult result : results) {
441
if (result.getError() == 0) {
442
System.out.println("Success: " + result.getType() + " on " + result.getForPath());
443
444
// For create operations, show actual path (important for sequential nodes)
445
if (result.getType() == OperationType.CREATE) {
446
System.out.println("Created at: " + result.getResultPath());
447
}
448
449
// Show stat information if available
450
Stat stat = result.getResultStat();
451
if (stat != null) {
452
System.out.println("Version: " + stat.getVersion());
453
System.out.println("Created: " + stat.getCtime());
454
}
455
} else {
456
System.err.println("Failed: " + result.getType() + " on " + result.getForPath() +
457
" Error: " + result.getError());
458
}
459
}
460
```
461
462
### Legacy Transaction Interface (Deprecated)
463
464
```java { .api }
465
/**
466
* Start a transaction builder (deprecated)
467
* @return builder object
468
* @deprecated use transaction() instead
469
*/
470
@Deprecated
471
CuratorTransaction inTransaction();
472
473
/**
474
* Legacy transaction interface
475
* @deprecated use CuratorMultiTransaction instead
476
*/
477
@Deprecated
478
public interface CuratorTransaction extends
479
CuratorTransactionBridge,
480
CuratorTransactionFinal {
481
// Legacy transaction methods
482
}
483
```